문제

라코 디스

정적 분석기가 마지막 줄에서 잘림에 대해 불평했습니다. 아마도 b가 비트가 뒤집 히기 전에 int로 승격되어 결과가 int 유형이 될 것이기 때문일 것입니다.

나는 승격 된 int의 마지막 바이트에만 관심이 있습니다. b가 0x55라면, a가 0xAA가되어야합니다.제 질문은 C 사양에 잘림이 발생하는 방식에 대해 언급하고 있습니까 아니면 구현이 정의 / 정의되지 않았습니까?a가 항상 내가 기대하는 값을 할당받을 것이라는 보장이 있습니까? 아니면 준수하는 플랫폼에서 잘못 될 수 있습니까?

물론 할당하기 전에 결과를 캐스팅하면 정적 분석기가 무음 화되지만 처음에이 경고를 무시해도 안전한지 알고 싶습니다.

도움이 되었습니까?

해결책

C99 표준 <인용구>

... 새 유형이 부호없는 경우 값이 새 유형의 범위에 들어갈 때까지 새 유형에서 표현할 수있는 최대 값보다 하나 더 많은 값을 반복적으로 더하거나 빼서 값을 변환합니다.

<시간>

CHAR_BIT의 예== 8, sizeof (unsigned char)== 1, sizeof (int)== 4

따라서 0x55는 int로, 0x00000055로 변환 된 다음 0xFFFFFFAA로 부정됩니다. 라코 디스

또는 예상대로 일반 유전자 태그 코드로

다른 팁

C 표준은 서명되지 않은 유형에 대해 다음을 지정합니다. <인용구>

부호없는 계산 피연산자는 오버플로 할 수 없습니다. 표현할 수없는 결과 결과적으로 부호없는 정수 유형은 다음과 같습니다. 모듈로 1 인 숫자 감소 가장 큰 값보다 결과로 나타낼 수 있습니다. 유형.

이 경우 귀하의 unsigned char가 8 비트이면 결과가 모듈로 256으로 줄어 듭니다. 즉, b0x55 인 경우 a는 실제로 0xAA가됩니다.

하지만 unsigned char가 8 비트보다 넓 으면 (완벽하게 합법적 임) 다른 결과를 얻게됩니다. 결과적으로 0xAA를 이식 가능하게 얻으려면 다음을 사용할 수 있습니다. 라코 디스

(비트 단위이며 unsigned char가 8 비트 인 플랫폼에서 최적화되어야합니다.)

또한 서명 된 유형을 사용하는 경우 결과는 구현에 따라 정의됩니다.

원하는대로 작동합니다.가치를 캐스팅하는 것이 안전합니다.

이 특정 코드 예제는 안전합니다.그러나 ~ 연산자를 느슨하게 사용하지 않도록 경고해야하는 이유가 있습니다.

이 이유는 ~ on small integer 변수는 C의 암시 적 정수 승격으로 인해 더 복잡한 표현식에서 잠재적 인 버그가되기 때문입니다. 다음과 같은 표현식이 있다고 상상해보세요.

a = ~b >> 4;

예상했던 것처럼 0으로 이동하지 않습니다.

정적 분석기가 MISRA-C를 포함하도록 설정된 경우 예를 들어 MISRA는 작은 정수 유형에 대한 모든 연산의 결과가 예상 유형 인 unsigned char로 명시 적으로 유형 변환되도록 강제하기 때문에 각 ~ 연산자에 대해이 경고를 받게됩니다.이 경우.

Win32 머신의 경우를 보겠습니다.
정수는 4 바이트이고 문자로 변환하면 왼쪽 3 바이트가 제거 된 것과 똑같이 결과가 나타납니다.

문자를 문자로 변환하므로 승격 대상이 무엇인지는 중요하지 않습니다.
~b will add 3 bytes at the left change 0s to 1 and then remove... It does not affect your one right byte.

다른 아키텍처 (16 비트 또는 64 비트 시스템)에 동일한 개념을 적용 할 수 있습니다.

리틀 엔디안이라고 가정

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top