i == (i = 2)의 결과는 무엇입니까?
다음 코드를 실행합니다.
// In Java, output #####
public static void main(String[] args) {
int i = 1;
if(i == (i = 2)) {
System.out.println("@@@@@");
} else {
System.out.println("#####");
}
}
그러나:
// In C, output @@@@@,I did test on Clion(GCC 7.3) and Visual Studio 2017
int main(int argc, char *argv[]) {
int i = 1;
if(i == (i = 2)) {
printf("@@@@@");
} else {
printf("#####");
}
return 0;
}
이 질문을 하는 동기는 다음 코드에서 비롯됩니다.
// The code is from the JDK 11 - java.util.concurrent.atomic.AtomicInteger
// I am curious about the behavior of the variable prev.
public final int getAndUpdate(IntUnaryOperator updateFunction) {
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext)
next = updateFunction.applyAsInt(prev);
if (weakCompareAndSetVolatile(prev, next))
return prev;
haveNext = (prev == (prev = get()));
}
}
그러면 위의 두 가지 실행 모드를 어떻게 설명해야 할까요?
식을 실행하는 C 프로그램의 동작i == (i = 2)
정의되지 않았습니다.
- 스칼라 개체에 대한 부작용이 동일한 스칼라 개체에 대한 다른 부작용이나 동일한 스칼라 개체의 값을 사용하는 값 계산과 관련이 없는 경우 동작이 정의되지 않습니다.식의 하위 표현식에 허용 가능한 순서가 여러 개 있는 경우 순서가 지정되지 않은 부작용이 임의의 순서에서 발생하면 동작이 정의되지 않습니다.84)
그i
의 왼쪽에==
스칼라 객체의 값에 대한 값 계산입니다.i
그리고 오른쪽.i = 2
값을 할당하는 부작용이 있습니다.2
로.i
의 LHS 및 RHS==
서로 순서가 정해지지 않은 상태입니다.따라서 전체 프로그램은 C에서 의미가 없습니다.
컴파일 대상gcc -Wall
GCC가 내뱉을 겁니다
unsequenced.c:5:16: warning: operation on ‘i’ may be undefined [-Wsequence-point]
if(i == (i = 2)) {
~~~^~~~
C와는 달리 자바는 피연산자에 대한 평가 순서를 보장합니다.
haveNext = (prev == (prev = get()));
Java에서는 정확합니다.LHS 값은 RHS에 대한 부작용 평가가 발생하기 전에 엄격하게 결정됩니다.
C에서 당신은 이것을 다음과 같은 것으로 써야 합니다.
newPrev = get();
haveNext = (prev == newPrev);
prev = newPrev;
Java 언어 사양(§15.7)은 다음과 같이 명시되어 있습니다.
Java 프로그래밍 언어는 연산자의 피연산자가 특정 평가 순서, 즉 왼쪽에서 오른쪽으로 평가되는 것을 보장합니다.
사양(§ 15.21.1)에도 다음 사항이 명시되어 있습니다.
이를 통해 산출되는 가치
==
연산자는true
왼쪽 피연산자의 값이 오른쪽 피연산자의 값과 같으면, 그렇지 않으면 결과는 다음과 같습니다.false
.
따라서 자바에서 실행 시 if-statement는 다음과 같이 보일 것이며, 이는 명백히 다음과 같이 평가됩니다.false
:
if (1 == 2) {
}
C에서는 단순히 정의되지 않았습니다(앤티의 대답 참조).
C에서 동작은i == (i = 2)
개체를 업데이트하고 중간 시퀀스 포인트 없이 해당 개체의 값을 계산에 사용하려고 하므로 정의되지 않았습니다.결과는 컴파일러, 컴파일러 설정, 심지어 주변 코드에 따라 달라집니다.
언급URL : https://stackoverflow.com/questions/53577739/what-is-the-result-of-i-i-2
'programing' 카테고리의 다른 글
현재 사용자 언어 찾기 (0) | 2023.06.20 |
---|---|
그룹별 변수의 최소값에 해당하는 행 추출 (0) | 2023.06.20 |
형식 암시의 하위 클래스 (0) | 2023.06.20 |
Ruby에서 GUID 생성 (0) | 2023.06.20 |
Oracle PL/SQL에서 <, > 및 & 문자를 html 엔티티로 이스케이프하는 방법 (0) | 2023.06.20 |