이 구조는 어떻게 sizeof == 0을 가질 수 있습니까?
를 sizeof
반환 할 구성을 요청하는 오래된 게시물이 있습니다 0
. 표준에 따라 어떤 유형이나 변수도 0의 크기를 가질 수 없다는 높은 평판 사용자의 높은 점수 답변이 있습니다. 그리고 저는 그것에 100 % 동의합니다.
그러나이 솔루션을 제시하는 새로운 답변 이 있습니다.
struct ZeroMemory {
int *a[0];
};
나는 막 반대표를 던지고 댓글을 달려고했지만 여기서 보내는 시간은 내가 100 % 확신하는 것조차 확인하는 법을 배웠다. 그래서 ... 놀랍게도 모두 gcc
와 clang
동일한 결과를 보여줍니다 sizeof(ZeroMemory) == 0
. 더욱이 변수의 크기는 0
다음과 같습니다.
ZeroMemory z{};
static_assert(sizeof(z) == 0); // Awkward...
뭐 ...?
이것이 어떻게 가능한지?
C가 표준화되기 전에는 코드에서 크기가 0 인 유형에 대한 포인터 하나를 다른 유형에서 빼려고하지 않는 한 많은 컴파일러가 크기가 0 인 유형을 처리하는 데 어려움이 없었을 것입니다. 이러한 유형은 유용했으며 지원하는 것이 금지하는 것보다 쉽고 저렴했습니다. 그러나 다른 컴파일러는 이러한 유형을 금지하기로 결정했으며 일부 정적 어설 션 코드는 코드에서 크기가 0 인 배열을 만들려고하면 삐걱 거리는 사실에 의존했을 수 있습니다. 표준 작성자는 다음과 같은 선택에 직면했습니다.
이러한 선언의 목적이 진단을 트리거하고 컴파일을 중단하는 경우에도 컴파일러가 크기가 0 인 배열 선언을 자동으로 수락하도록 허용하고 모든 컴파일러가 크기가 0 인 객체를 생성하는 것처럼 이러한 선언을 수락하도록 요구합니다 (반드시 침묵하지는 않음). .
이러한 선언의 목적이 진단을 트리거하고 컴파일을 중단하는 경우에도 컴파일러가 크기가 0 인 배열 선언을 자동으로 받아들이도록 허용하고 이러한 선언을 접한 컴파일러가 컴파일을 중단하거나 여유 시간에 계속할 수 있도록합니다.
코드가 크기가 0 인 배열을 선언하는 경우 구현에서 진단을 발행하도록 요구하지만, 구현이 여유 시간에 컴파일을 중단하거나 계속 진행할 수 있도록합니다 (적합하다고 생각하는 의미에 관계없이).
표준의 저자는 # 3을 선택했습니다. 결과적으로 표준 "확장자"에서 크기가 0 인 배열 선언은 표준에서 금지하기 전에 널리 지원 되었음에도 불구하고 간주됩니다.
C ++ 표준은 빈 개체의 존재를 허용하지만, 빈 개체의 주소를 토큰으로 사용할 수 있도록 허용하기 위해 최소 크기 1을 요구합니다. 구성원이없는 개체의 경우 크기는 따라서 0은 표준을 위반합니다. 그러나 개체에 크기가 0 인 멤버가 포함 된 경우 C ++ 표준은 이러한 선언을 포함하는 프로그램이 진단을 트리거해야한다는 사실 외에는 처리 방법에 대한 요구 사항을 부과하지 않습니다. 이러한 선언을 사용하는 대부분의 코드는 결과 개체의 크기가 0 일 것으로 예상하므로 이러한 코드를 수신하는 컴파일러에게 가장 유용한 동작은 이러한 방식으로 처리하는 것입니다.
Jarod42에서 지적한대로 크기가 0 인 배열은 표준 C ++가 아니라 GCC 및 Clang 확장입니다.
추가 -pedantic
하면 다음 경고가 생성됩니다.
5 : <source>:5:12: warning: zero size arrays are an extension [-Wzero-length-array] int *a[0]; ^
나는 std=c++XX
(대신 std=gnu++XX
) 모든 확장 기능을 비활성화하지 않는다는 것을 항상 잊습니다 .
이것은 여전히 sizeof
동작을 설명하지 않습니다 . 하지만 적어도 우리는 그것이 표준이 아니라는 것을 알고 있습니다.
C ++에서 크기가 0 인 배열은 불법입니다.
ISO / IEC 14882 : 2003 8.3.4 / 1 :
[..] 상수 표현식 (5.19)이 존재 하면 정수형 상수 표현식이고 그 값은 0보다 커야한다 . 상수 표현식은 배열의 경계 (요소 수)를 지정합니다. 상수 식의 값이있는 경우
N
, 어레이 갖는다N
번째 요소0
로N-1
, 그리고 상기 식별자의 종류D
인 " 유도 - 선언자 형리스트 배열N
T를". [..]
g ++에서는 -pedantic
크기가 0 인 배열에 경고를 표시하기 위해 플래그가 필요합니다 .
길이가 0 인 배열은 GCC 및 Clang의 확장입니다. sizeof
길이가 0 인 배열에 적용 하면 0으로 평가됩니다 .
C ++ 클래스 (비어 있음)는 size를 가질 수 없지만 0
클래스 ZeroMemory
가 비어 있지 않습니다. 크기가 지정된 명명 된 멤버가 0
있으며 적용 sizeof
하면 0이 반환됩니다.
참고 URL : https://stackoverflow.com/questions/47352663/how-can-this-structure-have-sizeof-0
'Nice programing' 카테고리의 다른 글
div를 "탭 가능"으로 만드는 방법은 무엇입니까? (0) | 2020.10.12 |
---|---|
Docker는 7000에서 8000까지의 모든 포트 또는 포트 범위를 노출합니다. (0) | 2020.10.12 |
확장 방법을 모의하기 위해 Moq를 어떻게 사용합니까? (0) | 2020.10.12 |
JSON 문자 인코딩-브라우저에서 UTF-8을 잘 지원합니까 아니면 숫자 이스케이프 시퀀스를 사용해야합니까? (0) | 2020.10.12 |
MySQL 대 SQL Server 대 Oracle (0) | 2020.10.12 |