2013-03-27 3 views
3

C++ 프로그램의 다음 부분을 고려하십시오. 콘솔에 인쇄 된 값은 주석으로 제공됩니다.식의 유형

{ // case 1 
unsigned int x = 10; 
unsigned int y = 20; 
std::cout << "u/u x - y: " << x-y << std::endl; // 4294967286 
} 

{ // case 2 
int x = 10; 
int y = 20; 
std::cout << "s/s x - y: " << x-y << std::endl; // -10 
} 

{ // case 3 
unsigned int x = 10; 
int y = 20; 
std::cout << "u/s x - y: " << x-y << std::endl; // 4294967286 
} 

{ // case 4 
int x = 10; 
unsigned int y = 20; 
std::cout << "s/u x - y: " << x-y << std::endl; // 4294967286 
} 

나는 C++의 (GCC 4.7.2로 시도) 표현에서 유형 (더 구체적으로, 그 부호의)를 정의하는 방법을 알아 내려고 노력하고있어.

10 = b00000000000000000000000000001010 
-20 = b11111111111111111111111111101100 
     b11111111111111111111111111110110 
: 그것은 -20을 얻을하고 추가 2의 보수를 할 것, 그리고

10 = b00000000000000000000000000001010 
20 = b00000000000000000000000000010100 

: 경우 1, 3, 4의 경우, 일반적인 산술 변환은 부호없는 INT에 두 값을 촉진한다

부호없는 정수로 해석하면 4294967286이됩니다.

분명히 사례 2에 대해 동일한 계산/결과를 얻습니다. 그러나 일반적인 산술 변환으로 인해 두 피연산자가 모두 부호가있는 int로 해석되어야하며 결과는 정수로 해석되는 것으로 보입니다.

여기에서 필자는 피연산자가 일반적인 산술 변환 후에 서명 된 경우 그 결과가 서명됨을 추론합니다. 그렇지 않은 경우 결과는 부호 없음입니다.

그래서, 내 질문은 :

  1. 내 공제가 맞습니까?
  2. 표준에서 이것을 어디에서 정의합니까? 이 C 또는 C++ 표준 참조를 찾을 수 없습니다.
  3. 다른 작업은 어떻게됩니까? 나는 +, *, 등등이 같은 방식으로 작동하지만, 교대 및 논리 연산은 어떨까요?

편집 :C++11 type of (signed + unsigned)?에 관한 것,하지만 내 질문의 중요한 부분이 허용 대답에서 누락 된 것 같다 : 식의 결과는 항상 보통의 산술 후 두 피연산자의 유형이 될 것입니다 전환?

+0

이 게시물을 확인하십시오. http://stackoverflow.com/questions/2280663/in-ac-expression-where-unsigned-int-and-signed-int-are-present-which-type-will – spartacus

답변

7

변환은 정수 변환 순위 원칙을 따릅니다. 요컨대, 정수 피연산자가 다음과 같은 경우 :

  • 정확히 일치하지 않으면 변환이 발생하지 않습니다.

  • 같은 크기의 부호없는 문자가 우선됩니다.

  • 다른 크기의 작은 값은 큰 값으로 변환됩니다.큰 값이 부호없는 경우 작은 값은 부호없는 값으로 변환됩니다.

이 변환은 피연산자를 결과의 유형 인 동일한 유형으로 바꿉니다.

C++ 11 표준의 [expr]§9에 해당됩니다. 또한 [conv][conv.rank]과도 밀접하게 관련됩니다. 정확하게 적용되는 운영자는 [expr] 하위의 개별 운영자 설명에 나와 있습니다.

+0

사실,하지만 내 질문의 핵심은 피연산자의 형식이 항상 표현식의 유형을 결정하는지 여부와 관련이 있습니다 (예 : 연산자에 의존하지 않음). – rainer

+0

@rainer 답변을 확장했습니다. – Angew

+3

@rainer 예, 피연산자 유형은 거의 항상 결과 유형을 결정합니다. 예외 : '<<' , '>>','<<=' and '> =>'에있는 시프트 수 피연산자의 유형은 고려되지 않습니다. '! ==','! =','<', '>','<=', '> =','&&'그리고'|| '는 피연산자 유형에 상관없이 항상'bool' (C++) 또는'int' (C)를 생성합니다. –

2

좋아, 그건 간단 해요, 난 그냥 ... 표준을 오해는 C++ 11에서, §5 [EXPR] P9 : 기대

많은 이항 연산자 산술 또는 열거 형의 원인 변환의 피연산자와 비슷한 결과를 도출 할 수 있습니다. . 그 결과는 유형이기도 한 공통 유형을 산출하는 것입니다.이 패턴을 일반적인 산술 변환이라고하며 ...

+0

그 표준의 어느 표준과 섹션을 언급하고 있는지 언급하십시오. – Richard

+1

@ 리차드 좋은 지적, 나는 내 대답을 업데이 트했습니다. – rainer