C에서 열거 형의 크기는 얼마입니까?


최상의 답변

시스템 경계 또는 네트워크 프로토콜을 넘어 구조 오프셋을 일치시켜야하는 매우 어려운 수수께끼 . 사양에 따르면 크기는 취할 수있는 가장 큰 값을 나타내는 데 필요한 최소값이어야합니다. 예를 들어 일반적인 상태 머신 상태 열거 형에는 바이트 만 필요할 수 있습니다.

크기를 제어하는 ​​AFAIK는 세 가지 방법 만 있습니다.

일부 (전체는 아님) 컴파일러에는 크기를 sizeof (int) 또는 32 비트로 강제하는 컴파일러 스위치 스위치 구문은 MSC와 gccc / clang간에 동일하지 않습니다.

두 번째 방법은 16 비트 필드를 채워야하는 경우 해당 크기가 필요한 더미 최대 값을 정의하는 것입니다.

다른 방법은 구조체 정의에서 일반 int 스타일을 사용하는 것입니다.하지만 하나는 열거 형 이름으로 값을 표시하고 대신 정수만 가져 오는 디버거의 편리함을 포기합니다.

그런 다음 열거 형을 포함하는 구조체를 패딩되지 않고 패킹하도록 지정해야합니다.

Answer

일부 변수의 일부가없는 경우 xconst 또는 volatile이고 x는 배열 유형이 아닙니다. 그 다음 문장…

x = x;

… 대부분은 아무것도하지 않습니다. 잘 구성되어 있습니다. x가 미리 초기화되었다고 가정하면 ¹ 또한 잘 정의되어 있습니다. 할당이 제대로 정의되지 않았습니다. 몇 가지 잠재적 인 예외를 제외하고 프로그램의 상태를 실제로 변경합니다 (아래 참조).

x에 유형.

struct foo {

char buf[42];

int x;

};

struct foo x = { "Hello World", 18 };

x = x; // no big deal.

그렇다면 “실수”는 무엇입니까? 유용한 코드는 아니지만 해당 설명에 맞는 코드가 상당히 많습니다. 다른 일을하려고했지만 놓친 경우는 실수 일뿐입니다.

[부록 :이 과제의 쓸모가 없다는 점을 감안할 때 컴파일러는 당신이 할 가능성이 높기 때문에 경고하는 경향이 있습니다. id = “af7847d40e”>

는 다른 의미입니다.]

const 및 ? const에 대한 제한은 간단합니다. “읽기 전용”을 의미하므로 쓸 수 없습니다. 최소한 간단한 할당은 아닙니다.

volatile에 관한 것은 더 까다 롭습니다. 그 키워드는 그것으로 한정된 값이 구현에 보이지 않는 방식으로 수정 될 수 있고 그것에 쓰는 것은 부작용을 가질 수 있다고 말한다. 여기서 래홀을 파헤 치지 않고 실제로 휘발성 개체에 대해 수행 할 수있는 합리적으로 잘 정의 된 유일한 작업은 다음과 같습니다.

volatile int v;

int i;

i = v; // reads from v once, places into i.

v = i; // writes to v once with the contents of i.

volatile를 사용하면 그보다 약간 더 깔끔하게 할 수 있습니다. 그러나 약간만. 이것은 다른 날의 주제입니다. C ++ 20이 volatile의 일부 사용을 제외하고 모두 사용하지 않는 이유가 있습니다. 변경 사항은 상당히 합리적으로 보입니다.

위에서 몇 가지 가능한 예외를 언급했습니다. Jonas Oberhauser는 struct의 모든 패딩이 반드시 해당 할당에 의해 유지되는 것은 아니라는 점을 상기 시켰습니다.

또한 이론적으로 동일한 값이 여러 가지 방식으로 표현 될 수있는 경우 할당으로 인해 객체의 기본 표현이 변경 될 수 있습니다 .

당신의 프로그램은 두 가지 가능성에 둔감합니다. 하지만 객체의 기본 표현을 살펴보면 차이점을 볼 수 있습니다. 예를 들어 memcmp와 같은 기능이 눈에 띕니다. 마찬가지로 유형 punning을 사용하는 경우

¹ 그렇지 않은 경우 정의되지 않은 동작 다음 중 하나를 위반했을 가능성이 있습니다.

  • 자동 저장 기간이있는 개체의 값이 불확실한 동안 사용됩니다 ( 6.2 .4 , 6.7.9 , 6.8 ).
  • 등록 스토리지 클래스로 선언 할 수있는 자동 저장 기간의 객체를 지정하는 lvalue는 다음이 필요한 컨텍스트에서 사용됩니다. 지정된 개체의 값이지만 개체가 초기화되지 않았습니다. ( 6.3.2.1 ).

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다