2010-11-24 2 views
6

내가 가지고있는 경고 다음 (SP1와 VS2008 컴파일러)를 생성이 샘플 코드 :컴파일러에 단항 작업에 경고 부호 INT

경고 C4146를 : 부호없는 형식에 적용 단항 마이너스 연산자 , 부호 아직 결과

void f(int n) 
{ 
} 

int main() 
{ 
    unsigned int n1 = 9; 
    f(-n1); 
} 

그러나 기능가입일 : 코드

int 경고없이이 코드를 컴파일하면 안됩니다. (n 가장 가능성이 32 임)

답변

12

표준 5.3.1/7

단항의 피연산자 - 오퍼레이터 산술 열거 종류와 그 결과를 가진다는 피연산자의 부정이다. 적분 승격은 피연산자의 적분 또는 열거로 수행됩니다. 부호없는 수량의 음수는의 값을 2n에서 뺀 값으로 계산됩니다. 여기서 n은 수준이 올라간 피연산자의 비트 수입니다. 결과 유형은 승격 피연산자 유형 입니다.

그리고 Integral Promotion 4 단락.INT는 은 모든 값을 나타낼 수 있다면 5/1

char 형 체결 CHAR, 서명 숯불 짧은 INT 또는 부호 짧은 INT의 r- 수치 int 형의 r- 수치로 전환시킬 수있다 소스 유형; 그렇지 않으면 소스 rvalue는 의unsigned int 유형의 rvalue로 변환 될 수 있습니다.

즉, 부호없는 int는 int로 승격되지 않습니다.

15

x 경우 unsigned int 형이다, 그래서 다음 -x이며 2n-x 사실상 동일하다. 나는 C++ 표준의 "표현"장을 읽는 것이 좋습니다

f(-static_cast<int>(n)); 

: int 캐스팅 올바른 동작을 얻을 경고를 방지하려면. 여기서 표현식 -x에서 x에 대한 통합 프로모션이 발생한다는 것을 알 수 있습니다. 즉, 거의 모든 것이 int으로 승격되지만, unsigned int은 승격되지 않습니다. 이 매우 흥미로운 예제를

봐 :

template<class T> 
void f(T x) 
{ 
    //somehow print type info about x, e.g. cout << typeid(x).name() or something 
} 

int main() 
{ 
    char x; 
    f(x); 
    f(+x); 
    f(-x); 
} 

인쇄 :

char 
int 
int 

그러나 char - unsigned int 반면> int는, 중요한 행사입니다 -> int이 변환이

+0

프로모션의 인용과 정의에 대한 @ Andreas의 대답을 참조하십시오. –

+0

값 "9"와 작동하지만 일반적으로'(int) (- (unsigned) x)'및'- (int) x' x가 INT_MIN이면 마이너스를 적용하는 것이 정의되지 않은 오버 플로우이고 부호없는 값의 단항 빼기는 모든 부호없는 값에 대해 잘 정의되어 있기 때문에 정확히 동일하지 않습니다. 그래도 내가 틀렸다면 나를 정정하십시오. –

2

매개 변수는 값으로 전달됩니다. 함수 호출 f (-n1)에서 매개 변수를 함수에 전달하기 전에 연산자가 적용됩니다. 그러므로 경고.

0

컴파일러는 부호없는 int에 단항 빼기를 적용하는 것이 일반적이지 않으며 예상 한 결과를 제공하지 않을 수도 있음을 경고합니다. 이 경우 얻을 수있는 결과는 32 비트 컴파일러를 사용하는 경우 f (4294967287u)를 호출하는 것과 같습니다.