Is this explanation accurate for C code that will not compile?

The proposed question and answer to the question here .

Will the following code compile (in C)?

#define X 8; int main(void) { ++X; // will this line compile? }` 

I am not an expert in C, but I know some C ++ and thought: of course not, you cannot increase the number 8, it is an rvalue. Of course, the preprocessor replaces X with 8 before trying to compile, and when it tries to compile, for this reason it will not work. Again, I am one of those who reads the interview, so then I thought, who knows ...

Here is an explanation:

"Strictly speaking, the operand of the increment operator of a prefix (or postfix) must be an unmodifiable lvalue. Now that we know what an lvalue is, we need to ask ourselves if X has an l-value. X is a macro, which means that it does not identify memory space - macros use simple text replacement through the preprocessor. Since macros do not exist in the memory region, they are not lvalues. This means that X cannot be used as the operand of the prefix. Therefore, the code shown above will not compile. "

Is this explanation short, in my opinion?

How many errors can you find above? I think maybe this should be an interview question ...

And this is just ridiculous:

“Intuitively, you could say that the code above will not compile - not knowing exactly why. However, in the interview situation, you will have to give some arguments like the ones above. The simple yes or no answers simply will not cut him in an interview. " (!)

+6
source share
5 answers

Is this explanation short, in my opinion?

Yes.

"Strictly speaking, the operand of the prefix (or postfix) increment operator must be an unmodified lvalue ...

What? An unmodifiable lvalue is something like const int n; - you can take your address (via & ), but you cannot assign it (via = , += or ++ ). You cannot increase that which cannot be changed.

To quote the standard (clause 6.5.3.1, clause 1):

The operand of the prefx increment or decrement operand must be a qualified or unqualified real or pointer type and must be a modified value of lvalue.

um.

X is a macro, which means that it does not identify a place in memory - macros use simple text replacement through a preprocessor.

It's a fake copy. Macros do not exist in C *. They are part of a preprocessor that has no concept of lvalues, rvalues, expressions or memory. This particular macro expands to an integer constant, which is an rvalue, but the 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 operator expands to ++8 , and since 8 is an rvalue, it cannot be used as an argument to ++ (in any form), and therefore it will not compile. Also, depending on whether you want to compile this code as C89 or C99, leaving main without an explicit return value, probably gives undefined behavior.

* If this is the accepted answer, I suggest that I should clarify this bit: the preprocessor is part of the C programming language. It is specified in the C standard, and the compiler must implement preprocessing to be a C compiler. However, the C language (i.e. syntax, semantics, library, etc.) Does not interact with the preprocessor - as soon as you get to the scene where you start working with lvalues ​​and rvalues, the preprocessor has already been executed for a long time and all macros are fully expanded. Macros themselves do not have a place in the syntax, because they are not part of the "language". There was some debate (in Steve Jessop's answer) that the use of the term “language” is misleading here, and I agree with him that it is, I just can't find a better word to use.

+5
source

Incorrect explanation:

X is a macro, which means that it does not identify a place in memory - macros use simple text replacement through a preprocessor.

Precisely because macros are just a simple replacement for text, they can expand to lvalue or something else. For instance:

 int x; #define X x int main() { ++X; } 

in order. It is true that the macro itself has no place in memory, but this is not related to whether ++X; correct, since ++X; doesn’t mean that it “increases the macro X”, it means “expand the macro X, and then insert ++ on the front panel,; on the back panel and parse the result".

What explains the explanation of "macros", he should talk about integer constants. 8 not an lvalue value, and what's important here.

With this change, the explanation is in order [Edit - as Chris points out in the comment, it is still not in order, he writes: “the operand of the increment operator of the prefix (or postfix) must be an unmodifiable lvalue”: this should read “modifiable”]

+10
source

It will not compile for the same reason that:

 8 = 8+1; 

will not compile.

You cannot change (here increment) a constant.

+2
source

The explanation is true only that the code will not compile, but it is very wrong in all other aspects.

He completely overlooks the fact that the compiler will not see X , he will see ++8;; , so all the information about whether the operator can be applied to X does not make sense. It would be much better to answer simply “No” than to give such an explanation.

+2
source

It will not compile because the prefix operator requires location values. 8 is a constant, it fails. You can read more about L-value here: L-Value and R-value expressions

0
source

Source: https://habr.com/ru/post/895126/


All Articles