를 사용하여 함수의 크기를 확인할 때 sizeof()
항상 1 바이트를 얻습니다 . 이 1 바이트는 무엇을 의미합니까?
를 사용하여 함수의 크기를 확인할 때 sizeof()
항상 1 바이트를 얻습니다 . 이 1 바이트는 무엇을 의미합니까?
답변:
제약 위반이며 컴파일러 가이를 진단 해야 합니다. 그럼에도 불구하고 컴파일하면 프로그램에 정의되지 않은 동작이 있습니다 [실패 모드에 대한 설명을 위해 @Steve Jessop에게 감사하고 일부 컴파일러에서이를 허용하는 이유에 대해서는 @Michael Burr의 답변 참조 ] : From C11, 6.5.3.4./ 1:
sizeof
연산자 기능 유형이 식에 적용되지 않는다
-std=c11
, 없습니다 gnu11
. 이것은 정말 이상한 컴파일러 확장입니다.
sizeof(void)
GNU C로 1이다
-std=c11
: 누군가가 -std=c*
옵션을 광고 표준에 참조해야합니다 . 그들은 적합성 모드를 활성화하지 않고 단지 잘 구성된 프로그램이 컴파일되는 것을 막는 확장을 비활성화 할뿐입니다 (예를 들어 typeof
, 잘 구성된 C 프로그램이 변수 이름으로 사용할 수 있기 때문에 키워드가되는 것과 같이 , gcc
기본적으로이를 거부합니다) ). 잘못된 형식의 프로그램이 진단되지 않은 상태로 통과하도록 허용하는 확장을 추가로 비활성화하려면 -pedantic
또는 -pedantic-errors
.
이것은 정의되지 않은 동작이 아닙니다. C 언어 표준에서는 sizeof
연산자에 대한 제약 조건 위반이므로 함수 지정자 (함수 이름)와 함께 연산자를 사용할 때 진단이 필요합니다 sizeof
.
그러나 C 언어의 확장으로 GCC는 void
포인터와 함수 포인터 에 대한 산술을 허용 하며, 이는 a void
또는 함수 의 크기 를 1
. 결과적으로 sizeof
연산자는 GCC 를 사용 1
하여 void
또는 함수를 평가합니다 . 참조 http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith를
GCC에 또는 옵션을 sizeof
사용하여 이러한 피연산자와 함께 사용할 때 GCC가 경고를 발행하도록 할 수 있습니다 . 또는 .-pedantic
-Wpointer-arith
-Werror=pointer-arith
sizeof
함수가 UB가 아니라는 점을 제외하고는 UB에 대해 많이 언급하지 않았습니다 (다른 답변이 UB라고 언급했기 때문에 거의 언급했습니다). 하지만 문장을 구성하는 방식 때문에 혼란 스러웠을 것입니다. 더 명확하게. sizeof
함수는 UB가 아닙니다 (여러 답변이 주장했듯이). 제약 위반입니다. 따라서 진단이 필요합니다. GCC는이를 확장으로 허용합니다.
이것은 컴파일러 작성자가 귀신이 당신의 코에서 날아 오르게하는 대신 1의 값을 결정했음을 의미합니다. (사실, 그것은 sizeof
우리에게 다음과 같은 표현을 주었던 또 다른 정의되지 않은 사용이었습니다 . "이것이 첫 번째 요구라면 C 컴파일러 자체가 진단을 발행해야합니다. 당신의 프로그램에서 발생하는 진단은 구문 규칙이나 제약의 추가 위반에 대한 추가 진단을 발행 할 수있는 것처럼 (그런데 문서화 된 진단 메시지가 될 수있는) 악마가 당신의 코에서 날아 오르게 할 수도 있습니다. 어떤 이유로 든 선택). " https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8J
이것으로부터 컴파일러가 정의되지 않은 구조에 대한 응답으로하기로 결정한 모든 것에 대한 속어 "코 악마"가 있습니다. 1
이 경우이 컴파일러의 비강 악마입니다.
다른 사람들이 지적했듯이 sizeof ()는 유효한 식별자를 사용할 수 있지만 함수 이름에 대해 유효한 (정직하고 유효한) 결과를 반환하지 않습니다. 또한 "코에서 나오는 악마"증후군을 유발할 수도 있고 그렇지 않을 수도 있습니다.
프로그램 함수 크기를 프로파일 링하려면 중간 결과 디렉토리 (.obj / .o로 컴파일되거나 결과 이미지 / 실행 파일이있는 위치)에있는 링커 맵을 확인하십시오. 때때로이 맵 파일을 생성하거나 생성하지 않는 옵션이 있습니다. 컴파일러 / 링커에 따라 다릅니다.
함수에 대한 포인터의 크기를 원하면 모두 동일한 크기, 즉 cpu의 주소 지정 단어 크기입니다.
int x = 1;
있지만 표준 준수 컴파일러에는 그중 하나만 허용됩니다. 로 sizeof()
함수에 적용되고, 그것은 또는 설정 값을 반환하거나, 컴파일을 거부하거나 시간에 특정 레지스터에있어 무엇을 기준으로 임의의 값을 반환하지 않을 수 있습니다. 문자 그대로의 비강 악마는 가능성이 적지 만 표준 문자 내에 있습니다.
sizeof
에 대한 포인터에 적용하십시오 .
-pedantic
) 비준수 컴파일러가 있고 모든 프로그램에 정의되지 않은 동작이있는 것입니다.