Is the following statement valid in ANSI C? Is it really?

During my preparation for the ANSI C exam, I came across the following question -

Is the following statement valid?
If not, please make the necessary changes to make it valid.

Source statement: test(i++,i++); invalid because undefined behavior matches K & R p202

Argument evaluation order unspecified

But can I change it to the following statement? test(i+=2, i+=3) ?

The problem is that I did not see such an entry in K & R or any other source. But Xcode compiles it and starts without warning.

+6
source share
5 answers

Both are valid operators, i.e. legal C, and in both cases the behavior is undefined.

+12
source

To add to existing answers, the key is approval

 test(i+=2, i+=3) 

causes undefined behavior as much as

 test(i++,i++); 

because in both cases there is no sequence point planned for the comma separator in the list of function parameters, and therefore, you end up modifying the value of the same variable twice in the region of one point in the sequence. This causes undefined behavior .

+12
source

Statements are syntactically valid, both before and after the change. But the problem will remain. If you modify the object in an argument and the evaluation order is not specified.

C99 Section 6.5.2.2 Clause 10

The order of evaluation of the function pointer, the actual arguments and the subexpressions in the actual arguments is undefined, but there is a sequence point before the actual call.

In accordance with section 3.4.4. Paragraph 1

unspecified behavior

use of an indefinite value or other behavior when this International Standard provides two or more possibilities and imposes no additional requirements for which are not selected in any case.

On the other hand, section 3.4.3. Point 1 reports

undefined behavior

when using an intolerable or erroneous program or erroneous data for which this International Standard does not impose any requirement

In the case of an order or evaluation, this can be done in any order, depending on how the compiler generates the code, it can be stored in memory in any order, and it can also pass arguments through the register. Once the code is generated, the binary will behave the same everywhere. Therefore, for a single binary file, the results will be the same every time, but depending on the decision of the compiler things can change.

The best idea is to avoid anything that seems wrong or fantastic. If in doubt, this behavior may be undefined, undefined, defined by the implementation. Therefore, you can do the same thing unambiguous and determinate as follows.

 test (i, i+1); i += 2; 

OR

 test (i+1, i); i+= 2; 

Depending on which order you want.

+7
source

This sentence is rather confusing: test(i++,i++); it is incorrect because undefined behavior corresponds to K & R p202.

True, this statement has always been unacceptable in C From the original C specification by Kernighan and Ritchie in their book "C Programming Language" to the latest C11 standard published several years ago, including the older C99 standard and the obsolete C89 standard, also known as ANSI C. Just for no reason.

The order in which the functions of the test function are evaluated is not specified, but this is not a problem here: both expressions change the same variable, and there is no sequence point between the evaluation of the function argument. Therefore, no matter how you achieve side effects in the expressions used for the arguments, you invoke undefined behavior. The compiler can generate code, but the rocket can explode on takeoff.

+4
source

As others have already noted, the behavior in both cases is undefined, even if the code is syntactically valid in both cases. I assume that the question uses β€œvalid” to mean β€œcorrect,” as in a strictly corresponding C program. To make a statement correct, you must first find out / get its intention.

This may be virtually impossible without some external source telling you exactly what the intent is, but let's say for the argument that the programmer wants to call the test function with parameters (i+1, i+2) (in order of appearance). It would be best to communicate this intention simply:

 test (i + 1, i + 2); i += 2; 

avoiding any harmful consequences introduced by an unspecified procedure for evaluating function arguments.

+4
source

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


All Articles