2016-09-27 8 views
1

C는 이진 연산자를 어떻게 처리합니까? 표준에 컴파일러가 LVALUE로 변환 할 필요가 있거나 필요하지 않습니까? 이러한 정의와C 바이너리 연산자가 LVALUE 또는 RVALUE의 너비에 적용됨

typedef union { 
    unsigned long _Data; 
    struct { 
    unsigned long _Reserved : 28; 
    unsigned long _Info  : 1; 
    unsigned long _Reserved2 : 3; 
    }; 
} S_INFO; 

S_INFO Variable; 

,

Variable._Data &= ~3uL; 

는 16 비트 아키텍처에서

Variable._Data &= ~3u; 

지시 다른 컴파일 명령어를 다음과 같이

구체적인 문제는 내가는 모습을 발견 at, int는 2 바이트 폭이고 4 바이트는 4 바이트입니다.

컴파일러가 & 연산자를 LVALUE Variable._Data 너비가 아닌 리터럴 (RVALUE) 너비에 적용한 것처럼 보입니다.

C 표준에 따라 컴파일러 버그를 발견 했습니까? 아니면이 올바른 동작입니까?

+0

추가 정보는 다음 2 명령은 Variable._Data의 상위 16 비트를 클리어한다. – Coda

+0

밑줄 + 대문자로 시작하는 이름은 구현을 위해 예약되어 있으므로 사용하지 마십시오! (소문자를 사용할 수도 있지만, C에서는 회원들에게 공통적이다.) – Olaf

+0

펜 및 용지를 가져 와서 두 상수의 비트 패턴을 적어 둡니다. 그런 다음 해당 패턴의 표현식을 수동으로 처리하십시오. – Olaf

답변

0

코드의 두 조각이 어떻게 다르게 컴파일되는지에 대한 결과를 게시 할 때까지 기다리고있는 동안 (내 의견에는 대답을 생각해내는 것처럼 보입니다. 그러나 이것이 옳은 대답), 나는 단지 일어나고있는 것이 바로 이것이라고 말하자.

명령어 Variable._Data &= ~3uL;은 부호없는 long 리터럴이 long 값과 AND 연산되도록한다.

명령어 Variable._Data &= ~3u;은 부호없는 (은 아니며이 아님) 리터럴을 사용하고 길이를 0으로 확장 한 다음 긴 값을 사용하여 AND합니다.

따라서이 명령어는 오른쪽 피연산자에서 리터럴을 선언하는 방식 때문에 다르게 컴파일됩니다. 이것은 아마도 왼쪽 피연산자와 아무 관련이 없으며 피연산자간에 수행하는 연산과도 관련이 없습니다.

어쨌든,이 시점에서, 이것은 내 추측입니다. 코드의 두 단편이 어떻게 다르게 컴파일되는지에 대한 결과를 게시하십시오. 그러면 제 대답을 수정할 수 있습니다.

그것은 버그가 아닙니다
+1

추가 정보 : 두 번째 명령은 Variable._Data의 상위 16 비트를 지 웁니다. – Coda

+0

아, 그리워. –

+0

너무 짧은 시간에 이전 댓글을 수정하는 중 .... 죄송합니다.이 플랫폼을 처음 사용합니다. 답변 해 주셔서 감사합니다. 이것은 기본적으로 "컴파일러는 아마도 캐스트를 수행하지만 바이너리가 아닌 후에 만 ​​수행합니다."라고 가정합니다. 답변에 대해서는 해체를 조사했습니다. 결과는 "추가 정보 : 두 번째 명령이 Variable._Data의 상위 16 비트를 지 웁니다."에서 설명한 것입니다. 이것은 기본적으로 당신이 생각한 것입니다. Btw, [link] (https://ideone.com/XKu5rI)에서도 문제가 재현되었습니다. 서로 다른 작업이 분리되면 더 포괄적이됩니다. – Coda

0

,이 두 표현은 동일하지 :

Variable._Data &= ~3uL; 

Variable._Data &= ~3u; 

이 모두 제로 아웃됩니다 최하위 2 비트. 그러나 두 번째 것만이 가장 중요한 16 비트를 제로 아웃합니다. 귀하의 기계에 기억, 유형 int는 16 비트의 너비와 32 비트의 너비가 있습니다.

&= 연산을 수행하기 전에 단항 문자 ~이 정수 리터럴에 적용됩니다.(컴퓨터에) 차이는 다음과 같습니다

작동 ~ 3U이 결과 0xfffffffc로 : 0xFFFC 다음 긴로 승격됩니다 : 0x0000FFFC

두 값을 적용하는 결과에

작동 ~ 3LU 결과 on Variable._Data은 위에서 설명한 것과 다릅니다.

Variable._Data &= 0xFFFFFFFC; 

및 두번째이다 :

첫 번째이다

Variable._Data &= 0x0000FFFC;