문제

§5.1.2.4.16

EXAMPLE 7 The grouping of an expression does not completely determine its evaluation. In the following fragment:

#include <stdio.h>
int sum;
char *p;
/*
...
*/
sum = sum * 10 - '0' + (*p++ = getchar());

the expression statement is grouped as if it were written as

sum = (((sum * 10) - '0') + ((*(p++)) = (getchar())));

but the actual increment of p can occur at any time between the previous sequence point and the next sequence point (the ; ), and the call to getchar can occur at any point prior to the need of its returned value.

So basically I understand this as unspecified behavior - either *p = getchar(); p++; OR p++; *p = getchar(). Note that the ; implies a sequence point, but there are no other sequence points in the whole expression.

So this syntax is useless. And, pretty much, ++ and -- for pointer assignment is useless. Right?

도움이 되었습니까?

해결책

either *p = getchar(); p++; OR p++; p* = getchar() [sic]

Well actuall no. It's either:

*p = getchar(); p++

or

old_p = p++; *old_p = getchar()

In your interpretation, you could either write at *p or *(p + 1) which is not true. In both interpretations, you write to where p originally pointed to, regardless of when the compiler decides to put the instruction that changes p. If it decides to put it before the write to *p, then it would have to make sure it keeps the old value to later write to (*old_p).

The suffix -- and ++ operators are actually quite nice shortcuts. Take this example:

size_t strlen(const char *str)
{
    size_t len = 0;
    while (str[len++]);
    return len - 1;
}

This is a very concise implementation of strlen using suffix ++.


From C11, 6.5.2.4.2 (emphasis mine):

The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it). See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. The value computation of the result is sequenced before the side effect of updating the stored value of the operand. With respect to an indeterminately-sequenced function call, the operation of postfix ++ is a single evaluation. Postfix ++ on an object with atomic type is a read-modify-write operation with memory_order_seq_cst memory order semantics.

다른 팁

The lexical grouping is irrelevant. What matters is the value of p++.

The statement is identical to the following two statements:

sum = sum * 10 - '0' + (*p = getchar());
++p;
sum = (((sum * 10) - '0') + ((*(p++)) = (getchar())));

is equivalent to

*p = getchar();
sum = ( ((sum * 10) - '0') + *p );
p++;

it was reduced to 1 line. and it's not useless because writing code in such way will allow to reduce the size and the complexity of your code

sum = (((sum * 10) - '0') + ((*(++p)) = (getchar())));

is equivalent to

p++;
*p = getchar();
sum = ( ((sum * 10) - '0') + *p );

Using -- and ++ for pointer assignments isn´t actually useless. Consider a loop where you want to read 10 characters and add the escape character at the end:

int i, sum;
char * p;
p = (char*) malloc(11 * sizeof(char));

for (i = 0; i < 10; i++){
   sum = sum * 10 - '0' + (*p++ = getchar());
}
*p = '\0';
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top