컴파일러 경고(수준 4) C4866

'file(line_number)' 컴파일러는 operator_name 호출에 대해 왼쪽에서 오른쪽 평가 순서를 적용하지 않을 수 있습니다.

설명

C++17부터 연산자 ->*, []>><<의 피연산자가 왼쪽에서 오른쪽 순서로 평가되어야 합니다. 컴파일러가 이 순서를 보장할 수 없는 두 가지 경우는 다음과 같습니다.

  • 피연산자 식 중 하나가 값으로 전달된 개체이거나 값으로 전달된 개체를 포함하는 경우, 또는

  • /clr을 사용하여 컴파일할 때 피연산자 중 하나가 개체 또는 배열 요소의 필드인 경우.

컴파일러는 왼쪽에서 오른쪽으로 계산을 보장할 수 없는 경우 경고 C4866을 생성합니다. 이 경고는 C++17에서 이러한 연산자의 왼쪽에서 오른쪽 순서 요구 사항이 도입되었기 때문에 지정된 경우에만 /std:c++17 생성됩니다.

이 경고는 기본적으로 꺼져 있습니다. /Wall 또는 /wN4866을 사용하여 명령줄에서 N 수준경고로 사용하도록 설정하거나 소스 파일에서 #pragma 경고를 사용할 수 있습니다. 자세한 내용은 기본적으로 꺼져 있는 컴파일러 경고를 참조하세요.

이 경고는 C++17 표준에 대한 컴파일러 규칙 작업의 결과로 Visual Studio 2017 버전 15.9에서 도입되었습니다. Visual Studio 2017 버전 15.9 이전 버전의 컴파일러에서 경고 없이 컴파일된 코드는 이제 C4866을 생성할 수 있습니다. 특정 컴파일러 버전 이상에서 도입된 경고를 사용하지 않도록 설정하는 방법에 대한 자세한 내용은 컴파일러 버전별 컴파일러 경고를 참조하세요.

이 경고를 해결하려면 먼저 요소 평가에서 순서 종속 부작용이 발생할 수 있는 경우와 같이 연산자 요소의 왼쪽에서 오른쪽 평가가 필요한지 여부를 고려합니다. 대부분의 경우 요소가 평가되는 순서는 관찰 가능한 효과가 없습니다.

평가 순서가 왼쪽에서 오른쪽이어야 하는 경우 대신 참조로 const 요소를 전달할 수 있는지 여부를 고려합니다. 이렇게 변경하면 다음 코드 샘플에서 경고가 제거됩니다.

예시

이 샘플에서는 C4866을 생성하고 이를 해결하는 방법을 보여 줍니다.

// C4866.cpp
// compile with: /w14866 /std:c++17

class HasCopyConstructor
{
public:
    int x;

    HasCopyConstructor(int x) : x(x) {}
    HasCopyConstructor(const HasCopyConstructor& h) : x(h.x) { }
};

int operator->*(HasCopyConstructor a, HasCopyConstructor b) { return a.x + b.x; }

// This version of operator->* does not trigger the warning:
// int operator->*(const HasCopyConstructor& a, const HasCopyConstructor& b) { return a.x + b.x; }

int main()
{
    HasCopyConstructor a{ 1 };
    HasCopyConstructor b{ 2 };

    a->*b;        // C4866 for call to operator->*
};