views:

681

answers:

6

I'm just going through a bunch of C++ interview questions just to make sure there's nothing obvious that I don't know. So far I haven't found anything that I didn't know already, except this:

long value;
//some stuff
value &= 0xFFFF;

The question is "what's wrong with this code?" And hints that it's something to do with target architectures.

Unless the answer is just "value isn't initialized", I can't see any problem. As far as I can tell, it's just masking the 2 least significant bytes of the value, and long is guaranteed to be at least 2 bytes, so there's no problem there.

Could it possibly be that long might only be 2 bytes on the target architecture, and you might be losing the sign bit? Or perhaps that the 0xFFFF is an int and int is only 2 bytes?

Thanks in advance.

A: 

sounds like Big-Endian vs. Little-Endian to me. http://en.wikipedia.org/wiki/Endianness

pbh101
Highly unlikely to be endianness given this little context. For it to be an endianness issue, there'd have to be an 'address of' operation in there - or something along those lines.
Jonathan Leffler
Value-context operation do not depend on endianness. It is impossible to "see" endianness in C++ until you start inspecting [raw] memory.
AndreyT
+7  A: 

It's hard to know what the interviewer expected you to say. We sort of just have to guess.

My guess is that on some architectures, 0xFFFF will be a signed 16 bit value, while long is a signed 32 bit value. When you extend the constant so that it can be used to mask the long value, will be sign extended and become 0xFFFFFFFFl, which isn't what you intended at all.

Addendum: The code as written works correctly on all three of the compilers that I currently use, so this is indeed a guessing game of trying to figure out what the interviewer intended. A properly standards compliant 16 bit compiler would also generate correct code, so we are left with guessing whether there is something we missed, whether the example is not in fact broken, or whether the interviewer once used a 16 bit compiler that would treat 0xFFFF as a signed quantity when forced to extend it to a long. It would be interesting to ask him.

John Knoeller
Not possible. In C++ `0xFFFF` cannot be a signed 16-bit value. This value does not fit in range of signed 16-bit type, which means that the compiler is will be required to use the *unsigned* 16-bit type.
AndreyT
Are you sure that can happen? Hex literals always seem to have positive values. According to C++'s Standard: "If it is octal or hexadecimal and has no suffix, it has the first of these types in which its value can be represented: `int`, `unsigned int`, `long` `int`, `unsigned long int`". In other words, if value `2^16-1` could not fit `int`, it will have type `unsigned` (instead of representing an unspecified value resulting from interpreting the `F`'s as representational bit).
Johannes Schaub - litb
It's a _guess_ guys. For all we know there isn't any thing wrong with the code, and the interviewer just _thought_ he was showing broken code.
John Knoeller
@John Knoeller: No, what you seem to fail to understand is that there are things that can be reasonably expected to be different between the compilers (and even non-compliant sometimes), and there are things that are reasonably expected to be implemented correctly. *This* is one of the things that are implemented correctly by all compilers. Any compilers that didn't get this specific bit right were laughed out of existence long time ago. In any case, a falure to implement such a fundamental thing correctly immediately and undebatably disqualifies a compiler from being called "a C++ compiler".
AndreyT
@AndreyT: If an unsized constant is assumed by the compiler to be 16 bits in size, then it's almost certainly an old compiler.
John Knoeller
@John Knoeller: It is an old compiler platform-wise. But that doesn't necessarily mean that it should be broken in such a fundamental way.
AndreyT
@John Knoeller: What if I "apply my superior mind" and tell you that it is *not* broken? Will that do? :)
AndreyT
@AndryT: only if you don't want to get the job. The interviewer told you it was broken. Whether he's right or not, he believes it.
John Knoeller
What sense does it make to say "it's all fine" if we dunno what the interview maker wants to hear. I've given up on this one :)
Johannes Schaub - litb
+1  A: 

May I say, there is nothing wrong in this code unless the context or intention of the surrounding code is known!

ArunSaha
Well, I didn't write this in the OP, but the question actually asked "what *might* be wrong with this code?", so really it's asking you to make some assumptions about some reasonable context.
Peter Alexander
A: 

This might be a shot in the dark but assuming that the long vs int isn't the issue (others have posted answers answering just that) and that the 0xFFFF encompasses the whole amount required by the type, wouldn't this just be making value = 0xFFFF and there is no need for the bit manipulation? Isn't the bit manipulation redundant?

The only other thing I can see is if the person asking the question wanted you to realize that the missing data contained in the long would not be affected by just using 0xFFFF.

To me comes across a bit wacky of a question to ask based on how the question is being presented here or maybe it's just so obvious we are all over thinking it :)

Kelsey
Billy ONeal
+11  A: 

This problem with this code is that it does a bit-wise operation on a signed value. The results of such operations on negative values vary greatly for different integer representations.

For example consider the following program:

#include <iostream>

int main(void)
{
    long value;
    value = -1; // Some stuff
    value &= 0xffff;
    std::cout << "Value = " << value << std::endl;
}

On a two's-complement architecture the result is:

Value = 65535

On a one's-complement architecture the result is:

Value = 65534

On a sign-and-magnitude architecture the result is:

Value = 1
Dingo
Exactly. See this CERT report: https://www.securecoding.cert.org/confluence/display/seccode/INT13-C.+Use+bitwise+operators+only+on+unsigned+operands. In particular, according to the C standard (as referenced there), the results of bitwise operations on signed values are implementation-defined.
Brooks Moses
A one's-complement architecture?? Where can I buy one of those?
Hans Passant
@nobugz: there are plenty of PDP-11s changing hands on eBay. If you want something more modern, I heard somewhere that Unisys mainframes are one's-complement.
Mike Seymour
Looks nice on the wall? I'll need a bigger wall.
Hans Passant
A: 

I suspect we are all thinking too hard.

Whats wrong with this code is that value is not initialized. The question is - do you realize the &= (or += , -= /= etc.) is meaningless when used on an unitialized value?

If value is initialized then the behavior is well defined. The least significant 16 bits are preserved, the rest are zeroed out

pm100
I think everyone is assuming that `//some stuff` has variable initialization in it.
Tanzelax
Peter Alexander
then my second comment stands - if value is initialized then the behavior is well defined
pm100