Alleged interview question and answer here.
Will the following code compile (in C)?
#define X 8;
int main(void)
{
++X; // will this line compile?
}`
I am no expert in C, but I know some C++ and thought: of course not, you cannot increment the number 8, it is an rvalue. Of course the preprocessor replaces the X with the 8 before trying to compile, and when it does try to compile, it will fail for that very reason. Then again, I am the one reading interview question websites so then I thought who knows…
Here is the explanation given:
“Strictly speaking, the operand of the prefix (or postfix) increment operator must be a non-modifiable lvalue. Now that we know what an lvalue is, we must ask ourselves if X is an lvalue. X is a macro, which means that it does not identify a place in memory – macros use simple text replacement via the preprocessor. Because macros don’t exist in a region of memory, they are not lvalues. This means that X can not be used as an operand of the prefix increment operator. Thus, the code shown above will not compile.”
Is this explanation as bunk as I think it is?
How many errors can you find above? I think maybe that should be the interview question…
And this is just funny:
“Intuitively, you might be able to say that the code above will not compile – without knowing exactly why. However, in an interview situation, you will be expected to provide some reasoning like what’s given above. Simple yes or no answers just won’t cut it in an interview.” (!)
Yes.
What? A non-modifiable lvalue is something like
const int n;– you can take its address (via&) but you can’t assign to it (via=,+=, or++). You can’t increment something that’s not modifiable.To quote the standard (6.5.3.1 paragraph 1):
Ahem.
This is bogus. Macros don’t exist in the C language*. They’re part of the preprocessor, which has no concept of lvalues, rvalues, expressions, or memory. This particular macro expands to an integer constant, which is an rvalue, but macros themselves have nothing to do with any of the above. See Steve Jessop’s answer for a counterexample of a macro being an lvalue.
The correct answer is that the statement expands to
++8, and since8is an rvalue it cannot be used as an argument to++(in either form), and so it will not compile. Also, depending on whether you intend this code to be compiled as C89 or C99, leavingmainwithout an explicitreturnvalue probably gives undefined behavior.* If this is going to be the accepted answer, I suppose I ought to clarify this bit: the preprocessor is a part of the C programming language. It is specified in the C standard, and a compiler has to implement preprocessing in order to be a C compiler. However, the C “language” (i.e. the syntax, semantics, library, etc.) doesn’t interact with the preprocessor – once you get to the stage where you start dealing with lvalues and rvalues, the preprocessor has long since been done and all macros are fully expanded. The macros themselves don’t have any place in the syntax, since they aren’t part of the “language.” There was some debate (in Steve Jessop’s answer) about whether the use of the term “language” here is misleading, and I agree with him that it is, I just can’t find a better word to use instead.