다음 코드를 고려해 봅시다.
int main() {
int i = 2;
int b = ++i++;
return 3;
}
오류와 함께 다음과 같이 컴파일됩니다.
<source>: In function 'int main()':
<source>:3:16: error: lvalue required as increment operand
3 | int b = ++i++;
| ^~
이것은 나에게 공평하게 들린다. 후위 증분 코드로서 해석되도록, 프리픽스 증가보다 더 높은 우선 순위를 보유 int b = ++(i++);
하고 i
r- 수치이다. 따라서 오류가 발생했습니다.
이제 기본 우선 순위를 무시하기 위해 괄호로이 변형을 고려해 보겠습니다.
int main() {
int i = 2;
int b = (++i)++;
return 3;
}
이 코드는 3을 컴파일하고 반환합니다.이 코드는 저에게 공평하게 들리지만 첫 번째 코드와 모순되는 것 같습니다.
질문 : 왜 (++i)
가 lvalue
때 i
아닌가요?
감사!
업데이트 : 위에 표시된 오류 메시지는 gcc (x86-64 9.2)에서 온 것입니다. 정확한 렌더링은 다음과 같습니다.
gcc의 오류
Clang x86-64 9.0.0의 메시지 가 다릅니다 :
clang 오류
<source>:3:13: error: expression is not assignable
int b = ++i++;
^ ~~~
GCC를 사용하면 접미사 연산자에 문제가 있다는 인상을 받고 왜 ++i
OK i
가 아닌지 왜 방황 할 수 있습니다 . Clang을 사용하면 접두사 연산자에 문제가있는 것이 더 분명합니다.
답변
i
그리고 ++i
모두 lvalues하지만 i++
를 rvalue입니다.
++(i++)
접두어 ++
가에 적용 되므로 유효하지 않습니다 ( i++
r 값). 그러나 lvalue (++i)++
이므로 괜찮습니다 ++i
.
C에서는 상황이 다릅니다. i++
그리고 ++i
모두 우변입니다. (이것은 사람들이 C와 C ++가 동일한 규칙을 가지고 있다고 가정하는 것을 멈추어야하는 이유의 예입니다. 사람들은 이러한 가정을 질문에 삽입 한 후 반박해야합니다.)
답변
이 선언
int b = ++i++;
에 해당
int b = ++( i++ );
접미사 증분 연산자는 증분 전에 피연산자의 값을 반환합니다.
C ++ 17 표준 (8.2.6 증가 및 감소)에서
1 접미사 ++ 표현식의 값은 피연산자의 값입니다 … 결과는 prvalue 입니다.
단항 증분 연산자는 증분 후 lvalue를 반환합니다. 이 선언은
int b = (++i)++;
유효합니다. 예를 들어 쓸 수 있습니다
int b = (++++++++i)++;
C ++ 17 표준 (8.3.2 증가 및 감소)에서
1 접두사 ++의 피연산자는 1을 추가하여 수정됩니다. 피연산자는 수정 가능한 lvalue 여야합니다. 피연산자의 유형은 cv bool 이외의 산술 유형이거나 완전히 정의 된 객체 유형에 대한 포인터 여야합니다. 결과는 업데이트 된 피연산자입니다. 피연산자가 비트 필드 인 경우 lvalue 이며 비트 필드입니다.
C에서 두 연산자는 lvalue 대신 값을 반환합니다. C에서이 선언은
int b = (++i)++;
유효하지 않다.
답변
따라서 코드는 int b = ++ (i ++); i는 rvalue입니다.
아니요 i
는 rvalue가 아닙니다. i
lvalue입니다. i++
rvalue (구체적인 값)입니다.