[c] sizeof (x ++)가 왜 x를 증가시키지 않습니까?

다음은 dev C ++ 창에서 컴파일 된 코드입니다.

#include <stdio.h>

int main() {
    int x = 5;
    printf("%d and ", sizeof(x++)); // note 1
    printf("%d\n", x); // note 2
    return 0;
}

노트 1x 을 실행 한 후 6이 될 것으로 예상 됩니다 . 그러나 출력은 다음과 같습니다.

4 and 5

아무도 노트 1x 후에 왜 증가하지 않는지 설명 할 수 있습니까 ?



답변

로부터 C99 표준 (강조는 나의 것)

6.5.3.4/2

sizeof 연산자는 피연산자의 크기 (바이트)를 산출하며 표현식 또는 유형의 괄호로 묶은 이름 일 수 있습니다. 크기는 피연산자의 유형에 따라 결정됩니다. 결과는 정수입니다. 피연산자의 유형이 가변 길이 배열 유형 인 경우 피연산자가 평가됩니다. 그렇지 않으면 피연산자가 평가되지 않고 결과는 정수 상수입니다.


답변

sizeofA는 컴파일 시간 연산자 그래서 편집시에, sizeof그 연산은 결과 값으로 교체하자. 피연산자되어 평가되지 전혀 (그것이 가변 길이 배열 인 경우는 제외); 결과 의 유형 만 중요합니다.

short func(short x) {  // this function never gets called !!
   printf("%d", x);    // this print never happens
   return x;
}

int main() {
   printf("%d", sizeof(func(3))); // all that matters to sizeof is the 
                                  // return type of the function.
   return 0;
}

산출:

2

short내 컴퓨터에 2 바이트를 차지합니다.

함수의 리턴 유형을 다음으로 변경 double:

double func(short x) {
// rest all same

8출력으로 줄 것입니다 .


답변

sizeof(foo) 컴파일 타임에 표현식의 크기를 찾기 위해 정말로 열심히 노력합니다.

6.5.3.4 :

sizeof 연산자는 피연산자의 크기 (바이트)를 산출하며 표현식 또는 유형의 괄호로 묶은 이름 일 수 있습니다. 크기는 피연산자의 유형에 따라 결정됩니다. 결과는 정수입니다. 피연산자의 유형이 가변 길이 배열 유형 인 경우 피연산자가 평가됩니다. 그렇지 않으면 피연산자가 평가되지 않고 결과는 정수 상수입니다.

한마디로 : 가변 길이 배열은 런타임에 실행합니다. (참고 : 가변 길이 배열 은으로 할당 된 배열 이 아닌 특정 기능입니다 malloc(3).) 그렇지 않으면 표현식 유형 만 계산되고 컴파일시 유형 이 계산됩니다.


답변

sizeof컴파일 타임 내장 연산자이며 함수 가 아닙니다 . 괄호없이 사용할 수있는 경우 매우 분명합니다.

(sizeof x)  //this also works


답변

노트

이 답변은 복제본에서 병합되어 늦은 날짜를 설명합니다.

기발한

가변 길이 배열을 제외하고 sizeof 는 인수를 평가하지 않습니다. 우리는 C99 표준 초안의 6.5.3.4 운영자의 크기 2 문단 에서 이것을 볼 수 있습니다 .

sizeof 연산자는 피연산자의 크기 (바이트)를 산출하며 표현식 또는 유형의 괄호로 묶은 이름 일 수 있습니다. 크기는 피연산자의 유형에 따라 결정됩니다. 결과는 정수입니다. 피연산자의 유형이 가변 길이 배열 유형 인 경우 피연산자가 평가됩니다. 그렇지 않으면 피연산자가 평가되지 않고 결과는 정수 상수입니다.

주석 ( now removed )은 런타임에 이와 같은 것이 평가되는지 여부를 물었습니다.

sizeof( char[x++]  ) ;

그리고 실제로는 다음과 같이 작동 할 것입니다 ( 모두 라이브 참조 ).

sizeof( char[func()]  ) ;

둘 다 가변 길이 배열이기 때문입니다. 비록 어느 쪽에도 실용적이지는 않다.

가변 길이 배열은 C99 표준 섹션 6.7.5.2 배열 선언자 단락 4 에서 다룹니다 .

[…] 크기가 정수 상수 표현식이고 요소 유형에 알려진 상수 크기가있는 경우 배열 유형은 가변 길이 배열 유형이 아닙니다. 그렇지 않으면 배열 유형은 가변 길이 배열 유형입니다.

최신 정보

C11에서 VLA 경우에 대한 답변이 변경되며, 어떤 경우에는 크기 표현의 평가 여부가 지정되지 않습니다. 6.7.6.2 배열 선언자 섹션에서 :

[…] 크기식이 sizeof 연산자의 피연산자의 일부이고 크기 식의 값을 변경해도 연산자 결과에 영향을 미치지 않는 경우 크기 식의 평가 여부는 지정되지 않습니다.

예를 들어 다음과 같은 경우 ( 실제 참조 ) :

sizeof( int (*)[x++] )


답변

sizeof연산자 의 피연산자 가 평가되지 않으므로 다음을 수행 할 수 있습니다.

int f(); //no definition, which means we cannot call it

int main(void) {
        printf("%d", sizeof(f()) );  //no linker error
        return 0;
}

온라인 데모 : http://ideone.com/S8e2Y

즉, 함수 만 f사용하는 경우 함수를 정의 할 필요가 없습니다 sizeof. 이 기술은 C ++에서도 피연산자 sizeof가 평가되지 않으므로 C ++ 템플릿 메타 프로그래밍에 주로 사용 됩니다.

왜 이것이 작동합니까? sizeof연산자가 value 에서 작동하지 않기 때문에 작동 하지만 대신 표현식 유형 에서 작동 합니다. 따라서 당신이 쓸 때 sizeof(f()), 그것은 표현식 의 타입 에서 작동 f()하며 함수의 리턴 타입에 지나지 않습니다 f. 함수가 실제로 실행될 경우 어떤 값을 반환하더라도 반환 유형은 항상 동일합니다.

C ++에서는 다음을 수행 할 수도 있습니다.

struct A
{
  A(); //no definition, which means we cannot create instance!
  int f(); //no definition, which means we cannot call it
};

int main() {
        std::cout << sizeof(A().f())<< std::endl;
        return 0;
}

에, 같은 그러나 그것은 보인다 sizeof, 내가 처음의 인스턴스를 만드는거야 A서면에 의해, A()다음 함수를 호출 f작성하여 인스턴스에를 A().f()하지만, 그런 일이 발생하지 않습니다.

데모 : http://ideone.com/egPMi

다음은 다른 흥미로운 속성을 설명하는 또 다른 주제입니다 sizeof.


답변

컴파일 중에는 실행할 수 없습니다. 그래서 ++i/ i++일어나지 않을 것입니다. 또한 sizeof(foo())함수를 실행하지 않고 올바른 유형을 반환합니다.