Share via


컴파일러 경고(수준 2) C4146

부호 없는 형식에 적용된 단항 빼기 연산자, 결과는 여전히 서명되지 않음

부호 없는 형식은 음수가 아닌 값만 포함할 수 있으므로 부호 없는 형식에 적용할 때는 일반적으로 단항 빼기(부정)가 의미가 없습니다. 피연산자와 결과는 모두 음수가 아닙니다.

설명

음수 정수 리터럴 - 을 표현하면 값 앞의 값이 단항 부정 연산자로 구문 분석됩니다. 컴파일러는 숫자 값을 구문 분석한 후 연산자를 적용합니다. 숫자 값이 부호 없는 정수 형식의 범위에 맞지만 해당 부호 있는 정수 형식이 아닌 경우 컴파일러는 값을 부호 없는 것으로 해석합니다. 부호 없는 값은 단항 부정 연산자에 의해 변경되지 않습니다.

이 경고는 -2147483648 또는 long long 최소 int 값인 -9223372036854775808 표현하려고 할 때 종종 발생합니다. 이러한 값은 각각 -2147483648 또는 -9223372036854775808ll로 작성할 수 없습니다. 그 이유는 컴파일러가 식을 두 단계로 처리하기 때문입니다. 먼저 숫자 값을 구문 분석한 다음 부정 연산자를 적용하기 때문입니다. 예를 들어 컴파일러가 -2147483648 구문 분석할 때 다음 단계를 수행합니다.

  1. 2147483648 수가 평가됩니다. 2147483647 최대 int 값보다 크지만 여전히 2147483648 unsigned int유형입니다 unsigned int.

  2. 부호 없는 값에 단항 빼기(unary minus)가 적용되며 부호 없는 결과도 2147483648.

부호 없는 결과 형식으로 인해 예기치 않은 동작이 발생할 수 있습니다. 비교에 결과가 사용되는 경우 다른 피연산 int자일 때와 같이 부호 없는 비교를 사용할 수 있습니다.

C++ 등가<climits>를 사용 INT_MIN 하거나 LLONG_MIN C++에서 <limits.h> C4146을 방지할 수 있습니다. 이러한 값에는 서명된 형식이 있습니다.

/sdl (추가 보안 검사 사용) 컴파일러 옵션은 이 경고를 오류로 승격합니다.

예시

다음 샘플에서는 컴파일러에서 경고 C4146을 생성할 때 발생할 수 있는 예기치 않은 동작을 보여 줍니다.

// C4146.cpp
// compile with: /W2
#include <iostream>

void check(int i)
{
    if (i > -9223372036854775808ll)   // C4146
        std::cout << i << " is greater than the most negative long long int.\n";
}

int main()
{
    check(-100);
    check(1);
}

이 예제에서 컴파일러는 리터럴 ll 에 접미사가 있고 부정 연산자가 적용되더라도 -9223372036854775808ll을 부호 없는 것으로 간주합니다. 비교를 < 위해 컴파일러는 자동으로 서명 i 된 수준을 unsigned long long int승격합니다. 예상되는 두 번째 줄은 1 is greater than the most negative long long intfalse이므로 인쇄되지 ((unsigned long long int)1) > 9223372036854775808ull 않습니다.

예제를 수정하려면 -9223372036854775808ll을 LLONG_MIN포함합니다<climits>.

참고 항목

단항 부정 연산자(-)