C ++ 함수 매개 변수의 평가 순서


90

이렇게 구성된 세 가지 함수 (foo, bar, baz)가 있다면 ...

foo(bar(), baz())

C ++ 표준에 의해 baz 전에 bar가 평가된다는 보장이 있습니까?

답변:


102

아니요, 그런 보장은 없습니다. C ++ 표준에 따라 지정되지 않았습니다.

Bjarne Stroustrup은 또한 "The C ++ Programming Language"3 판 섹션 6.2.2에서 다음과 같은 몇 가지 이유를 가지고 명시 적으로 언급했습니다.

표현식 평가 순서에 대한 제한없이 더 나은 코드 생성 가능

기술적으로 이것은 표현식의 일부 평가 순서도 지정되지 않은 동일한 섹션의 이전 부분을 참조하지만, 즉

int x = f(2) + g(3);   // unspecified whether f() or g() is called first

나는 8 분 안에이 대답을 받아 들일 수있다.
Clark Gaebel

4
예, 그러나 표현식 평가 순서가 STRICT이면 더 나은 코드가 WRITTEN (= 깨끗함)이 될 수 있습니다. 이는 일반적으로 코드 생성보다 훨씬 더 중요합니다. 이 예를보십시오 : stackoverflow.com/questions/43612592/… 자 , Stroustrup.
Bill Kotsias 2017

1
주문이 중요한 경우 직접 시퀀싱을 수행 할 수 있습니다. 그렇지 않으면 항상 (드물게?) 중요하지 않은 무언가에 대한 비용이 발생합니다. 나는 당신이 사용하지 않는 것에 대해 지불하지 않는 정책이 대부분의 C ++ 프로그래머가 동의하는 유일한 것이라고 생각합니다.
tweej

3
"정의되지 않음"이 아닌 "지정되지 않은 동작"이어야하지 않습니까?
GoodDeeds

1
@ChrisDodd는 "정의되지 않음"대 "지정되지 않음"이라는 단어를 사용하여 허용 된 답변에 반대표를 던지는 것은 나에게 악의적 인 행보처럼 느껴집니다 ... 저는 이것이 "정의되지 않은 행동"이라고 말하지 않았고, 그렇지 않으면 "정의되지 않은"및 "지정되지 않은"것처럼 보입니다. 동의어? 어떤 경우에는, 대답에 편집을 제안이 논의하기 위해 좀 더 생산적인 방법이었을 것입니다
엘리 Bendersky

20

bar () 및 baz ()에 대해 지정된 순서가 없습니다. Standard가 말하는 유일한 것은 foo ()가 호출되기 전에 둘 다 평가된다는 것입니다. C ++ 표준, 섹션 5.2.2 / 8에서 :

인수 평가 순서는 지정되지 않습니다.


4
foo () 전에 평가된다는 사실은 적어도 약간 안심입니다.
Bill Kotsias 2017

1
@BillKotsias 표준은 또한 함수 호출이 겹칠 수 없다고 말합니다 (즉, 구현에서의 1 bar행,의 1 baz행,의 2 행 bar등을 실행할 수 없음 ). :-)
melpomene 19

20

[5.2.2] 함수 호출부터

인수 평가 순서는 지정되지 않습니다. 인수 표현식 평가의 모든 부작용은 함수가 입력되기 전에 적용됩니다.

따라서, 보장은 없습니다 bar()전에 실행 baz()것만, bar()그리고 baz()전에 호출됩니다 foo.

또한 [5] 표현식에서 다음 사항에 유의하십시오.

언급 된 경우를 제외하고 [예 : &&and에 대한 특수 규칙 ||], 개별 연산자의 피연산자 및 개별 표현식의 하위 표현식 평가 순서 및 부작용이 발생하는 순서는 지정되지 않습니다.

따라서 bar()에서 이전 baz()에 실행 할지 여부 를 묻는 경우에도 foo(bar() + baz())순서는 여전히 지정되지 않습니다.


4
로부터 "특수 메모」의 일례 [5.14] 논리적 AND 연산자"달리 &, &&보증 좌우로 평가 : 제 오퍼랜드 인 경우 상기 제 피연산자는 평가되지 않는다 false. "
Daniel Trebbien


2

C ++ 11에서 관련 텍스트는 8.3.6 Default arguments / 9 (Emphasis mine) 에서 찾을 수 있습니다.

함수가 호출 될 때마다 기본 인수가 평가됩니다. 함수 인수의 평가 순서는 지정되지 않습니다 . 따라서 함수의 매개 변수는 평가되지 않더라도 기본 인수에 사용되지 않습니다.

동일한 설명이 C ++ 14 표준에서도 사용되며 동일한 섹션 아래 에 있습니다 .


0

다른 사람들이 이미 지적했듯이 표준은이 특정 시나리오에 대한 평가 순서에 대한 지침을 제공하지 않습니다. 이 평가 순서는 컴파일러에게 맡기고 컴파일러는 보증 할 수 있습니다.

C ++ 표준은 실제로 컴파일러에게 어셈블리 / 머신 코드 구성에 대해 지시하는 언어라는 것을 기억하는 것이 중요합니다. 표준은 방정식의 한 부분 일뿐입니다. 표준이 모호하거나 구체적으로 구현이 정의 된 경우 컴파일러를 사용하여 C ++ 명령어를 실제 기계 언어로 변환하는 방법을 이해해야합니다.

따라서 평가 순서가 요구 사항이거나 적어도 중요하고 컴파일러 간 호환이 요구 사항이 아닌 경우 컴파일러가 궁극적으로이를 어떻게 결합할지 조사하면 궁극적으로 답이있을 수 있습니다. 컴파일러는 향후 방법론을 변경할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.