2011-05-03 7 views
12

나는 보통 컴파일러 경고 뒤에있는 이유를 이해할 수 있지만, 이것은 보통 명백한 것처럼 보인다.컴파일러 경고에 의아해 int8_t의 복합 할당이 int로 승격

#include <stdint.h>  
uint8_t myfunc(uint8_t x,uint8_t y) 
{ 
    x |= y; 
    return x; 
} 

-Wall을 가진 인텔 컴파일러는 불평이 권리는

conversion from "int" to "uint8_t={unsigned char}" may lose significant bits 
    x |= y; 
    ^

인가? 위의 코드는 이식성이없고 비표준 코드입니까?

+0

이 허용 대답의 설명을 요약하면 :

경고를 제거하는 방법은 당신이 의식적으로 캐스트와 비트를 버리고있는 컴파일러에게하는 것입니다 컴파일러는 기술적으로 바로 거기 int에서 uint8_t 로의 변환이지만, 실망스럽게도 중대한 비트를 잃어 버릴지도 모른다는 주장에서 위태로 우며 잘못되었습니다. –

답변

9

integer promotions : 자세한 내용은 this page를 참조하십시오, 첫 문장이 시작됩니다.

x |= y; 

| 운영자 모두의 피연산자는

다음

x = (int)x | (int)y; 

int을 촉진하는 결과 정밀도 손실 uint8_t로 다시 변환된다.

+4

"중요한 비트가 손실 될 수 있습니다"라는 경고 메시지가 나타납니다. 그것은 노골적으로 잘못되었습니다. 이 작업으로 비트를 잃을 수는 없습니다. –

+0

컴파일러는 물론 코드를 최적화하고 8 비트로 모두 할 수 있습니다. 그것은 여전히 ​​경고를 줄 것이다. –

+0

@R,'int' 또는'unsigned int'에서'uint8_t' 로의 변환은 잠재적으로 비트를 잃을 수 있습니다. 잃을 중요한 비트가 없다는 것을 알게되면 컴파일러 작성자에게는 큰 어려움이 없을 것입니다. –

5

맞습니다. 운영자는 인수를 int으로 승격합니다. [...]

없음 산술가 INT보다 짧은 정밀도로 C에 의해 수행되지 않습니다 직장에서

4

xy의 값은 int으로 승격되지만, 경고는 그럼에도 불구하고 위변조입니다. | 연산자는 uint8_t에서 승격 된 이후에 이미 uint8_t에 맞는 피연산자의 너비를 초과하여 결과 비트의 너비를 늘릴 수 없습니다. 이 경고 옵션 플래그의 대부분은 완전히 유효하고 올바른 코드이며 100 개의 질문에 시간을 낭비하지 않으려는 경우가 아니라면 경고를 끄거나 무시하는 것이 가장 좋습니다.

+0

암시 적 프로모션을 위해 실수로 준비하지 않은 경우가 있다는 경고가 표시되지 않도록하십시오. 사고로 루프에 서명하도록 서명되지 않은 사람이 승진했다면, 그 사실을 알고 싶을 것입니다. – AJG85

+0

@ AJG85 :하지만 질문은 * 당신이 그것에 대해 알고 있겠습니까? * - 경고가 묻혀있을 때이 옵션으로 생성 된 수백 가지의 가짜 경고가 발생합니다. 컴파일러 작성자가 경고를 수정하여 실제로 무언가가 잘못 될 수있는 상황에서만 트리거하는 것이 중요합니다. 그들이 가짜 경고로 홍수에 빠지면 (1) 무시하거나 (2) 옵션을 해제하십시오. 가짜 경보가 쇄도하는 가운데 더 높은 신호 대 잡음 비율을 가질 수있는 다른 유형의 경고 *를 숨기지 않으므로 옵션 (2)을 약간 더 잘 고려합니다. –

+0

나는 몇 바이트의 메모리를 절약 할 가치가있는 컴파일러와 싸우는이 질문을 던집니다. _ 경고는 실제로 있는지, 어떻게해야 할지를 아는 것보다 예에 대해서만 대답 할 수 있습니다. 나는 경고가 없지만'signed int' 연산을 수행 할 때'unsigned char'을 사용하지도 않습니다. – AJG85

1

컴파일러 경고는 작동이 8 비트 이상을 생성 할 수 없기 때문에 무의미한 것처럼 보일 수 있지만 더 큰 연산 클래스의 서브 세트 일뿐입니다. 예를 들어 |=+=으로 바꾼 경우 오버플로가 발생할 가능성이 매우 높습니다.

x = (uint8_t)(x | y); 
+0

당신이 비트를 던지지 않는 것을 제외하고는 ... –

+0

@R, 확실히 당신은 당신이 이미 그들이 모두 0이라는 것을 알고 있습니다. 어쩌면 나는 그것을 "의식적으로 상위 비트들을 무시하는"것으로 바꿔야 할 것이다. –