2010-08-14 5 views
23

일반적으로 C는 2 진수의 피연산자가 상위 피연산자의 유형으로 승격되도록 요구합니다. 이것은 예를 들어, 자세한 캐스트로 코드를 작성 피하기 위해 악용 될 수 있습니다비트 및 정수 승격?

if (x-48U<10) ... 
y = x+0ULL << 40; 

는 그러나, 나는 적어도 GCC와 함께,이 문제가 bitshifts 작동하지 않는 것으로 나타났습니다. 나는.

int x = 1; 
unsigned long long y = x << 32ULL; 

I 시프트가 성공하도록 왼쪽 피연산자가 unsigned long long로 승격되도록하기 위해 오른쪽 피연산자의 유형을 기대. 하지만 그 대신, GCC 인쇄 경고 : gcc가 고장난 또는 표준 bitshifts의 유형 승격 규칙 일부 예외를 않습니다

warning: left shift count >= width of type 

?

+0

경고에 관계없이 어쨌든 홍보 할 계획입니까? (결국 경고 일뿐입니다). –

+1

짧은 매크로를 사용하여 자세한 캐스트를 생성 할 수 없습니까? '#define ULL (x) ((unsigned long long) x)'처럼? – Borealid

+1

@ 로버트 : 아니요. 마치''32'라고 쓰여진 것처럼, 아무런 조작도하지 않습니다. @Borealid : 예, 할 수 있습니다. 그러나 추가 정의/헤더 없이도 어디서나 복사하여 붙여 넣을 수있는 코드를 작성하는 것이 좋습니다 (예 : 다른 프로젝트). 나는'typedef unsigned int uint;'와 같은 것을 싫어한다. –

답변

23

일반적인 산술 변환은 많은 이진 연산자에 적용되지만 모든 연산자가 이에 해당하지는 않습니다. 예를 들어, 비트 시프트 연산자 인 & &, ||, 쉼표 연산자 및 할당 연산자에는 적용되지 않습니다.

6.5.7 ... (3) ... 의미
정수 프로모션 피연산자의 각각에 수행된다 :이 비트 시프트 연산자에 대한 규칙이다. 결과 유형은 승격 된 왼쪽 피연산자의 유형입니다. 오른쪽 피연산자의 값이 음수이거나 승격 된 왼쪽 피연산자의 너비보다 크거나 같으면 동작이 정의되지 않습니다.

+1

고마워요,이게 내가 찾고 있던 것입니다. –

0

문제는 실제로 프로모션은 플랫폼에 따라 int으로 정의됩니다. 다른 답변에서 언급했듯이 비트 시프트 연산자는 왼쪽 피연산자를 int로 승격시킵니다. 그러나 여기서 int은 32 비트 값으로 정의됩니다. 정수 변환은 long long (64 비트)으로 승격되지 않습니다.