sizeof (int)가 맞고 sizeof int가 잘못된 이유는 무엇입니까?


97

우리가 알고 sizeof있는 데이터 타입 표현의 크기를 계산하기 위해 사용 연산자이며, 피연산자 표현하면, 괄호는 생략 될 수있다.

int main()
{
        int a;

        sizeof int;
        sizeof( int );
        sizeof a;
        sizeof( a );

        return 0;
}

의 첫 번째 사용법 sizeof은 잘못된 반면 다른 것은 옳습니다.

gcc를 사용하여 컴파일하면 다음 오류 메시지가 표시됩니다.

main.c:5:9: error: expected expression before int

내 질문은 C 표준이 이러한 종류의 작업을 허용하지 않는 이유입니다. 윌 sizeof int모호성의 원인?


5
재미있는 점은 모든 표현식이 괄호없이 허용되는 것은 아니라는 것입니다 : try sizeof (int)a.
Fred Foo

2
@MikkelK .: OP는 표시된 답변에 언급 된 인용문을 이미 알고있는 표준 인용문 뒤에 추론을 묻고 있습니다.
Alok 저장

2
@Lundin : sizeof +(int)a장점이 있습니다 이상 *&;-) 실제로 컴파일하는
스티브 Jessop

2
@SteveJessop 아 맞다, 그것은 lvalue가 아닙니다. Embarcadero C ++로 컴파일되었지만 이상하게도 충분합니다. 어쨌든, 나는 우리가 이제 단항 + 연산자에 대한 용도를 찾았다 고 믿습니다! 그것은 C 프로그래밍 역사상 처음 일 것입니다. :)
Lundin

2
@Lundin : 여전히 단항을 조심해야합니다 +. 예를 들어 sizeof +(char)a == sizeof(int)정수 승격으로 인해 크기를 가져 오려는 표현식에 대해 전혀 걱정할 필요가없는 경우 괄호 안에 넣는 것이 오류 발생 가능성이 적습니다. 아니에요 그래서 내가 ... 내가 그것을 사용 했 인정하지만 확실히 나는 지금까지 "용도"를 호출하기로 갈 것
스티브 Jessop에게

답변:


101

다음은 모호 할 수 있습니다.

sizeof int * + 1

그게 (sizeof (int*)) + 1아니면 (sizeof(int)) * (+1)?

분명히 C 언어는 모호성을 해결하기위한 규칙을 도입 할 수 있었지만 왜 그렇게 신경 쓰지 않았는지 상상할 수 있습니다. 언어를 그대로 사용하면 유형 지정자는 표현식에서 "네이 키드"로 표시되지 않으므로 해당 초가 *유형의 일부 인지 산술 연산자 인지 여부를 확인하는 규칙이 필요하지 않습니다 .

기존 문법은 이미 잠재적 인 모호성을 해결했습니다 sizeof (int *) + 1. 그것은이다 (sizeof(int*))+1, 하지 sizeof((int*)(+1)) .

C ++에는 함수 스타일 캐스트 구문으로 해결할 수있는 다소 유사한 문제가 있습니다. 당신은 쓸 수 있습니다 int(0)당신은 쓸 수 있습니다 typedef int *intptr; intptr(0);,하지만 당신은 쓸 수 없습니다 int*(0). 이 경우 해결 방법은 "naked"유형이 단순 유형 이름이어야하며 공백이 있거나 후행 구두점이있을 수있는 이전 유형 ID 일 수 없다는 것입니다. sizeof동일한 제한으로 정의 되었을 수도 있지만 확실하지 않습니다.


1
C ++에는 new int*(X)new 연산자가 유형이 될 수있는 가장 긴 문자열을 사용하도록 지정하지 않으면 모호한 것이 있습니다. 그래서 C ++에서 그들은 sizeof와 동일하게 만들 수 있었을 것입니다. 그러나 C ++에서는 sizeof int()어느 것이 모호했을지 말할 수 있습니다 (유형 또는 값 초기화 int?).
Johannes Schaub-litb

@ JohannesSchaub-litb : 음, 그럼 아마도 C ++에서 파싱이 가능하다면 타입이 선호되고 그렇지 않으면 표현식이라고 말할 수있을 것입니다. 모호성가 해결 될 수 있지만 sizeof int()( "아무 잘못 형성 될 것이다 operator()위한 size_t나는 환영받지 못하는 것이 기대되는")!
Steve Jessop

32

에서 C99 표준

6.5.3.4.2 연산자 식 또는 유형의 괄호 이름 일 수있다 피연산자의 크기 (바이트)를 산출한다.
sizeof

귀하의 경우 int에는 표현도 괄호 안의 이름도 아닙니다.


10
나는 이것이 왜 7 개의 찬성표를 얻는 지 이해하지 못합니다. 삭제 된 세 개의 답변과 마찬가지로 규칙이 존재하는 이유를 설명하는 대신 규칙을 반복합니다.
Fred Foo

8
@larsmans, 네, 동의합니다. 규칙을 계속 반복하지만 적어도 읽기 권한을 부여합니다.
Yishu Fang

3
@larsmans C99에서 내리는 모든 결정을 정당화하기 시작하면 일년 내내 여기에있을 것입니다. 표준을 인용하는 것은이 토론을 마무리하는 좋은 방법입니다.
Perry

1
@Perry : 이런 종류의 질문이 마음에 들지 않으면 투표로 질문을 종결 할 수 있습니다.
Fred Foo

4
C ++의 비 실무자로서 나는이 대답을 이해하지만 영어를 읽고 이해할 수 있다면 문제가 무엇인지 확실하지 않습니다.
Kev

6

C에서 sizeof 연산자를 사용하는 방법에는 두 가지가 있습니다. 구문은 다음과 같습니다.

C11 6.5.3 Unary operators
...
sizeof unary-expression
sizeof ( type-name )

유형을 피연산자로 사용할 때마다 언어의 구문 정의에 따라 괄호가 있어야합니다. 식에 sizeof를 사용하면 괄호가 필요하지 않습니다.

C 표준은 표현식에서 사용할 수있는 예를 하나 제공합니다.

sizeof array / sizeof array[0]

그러나 일관성과 운영자 우선 순위와 관련된 버그를 피하기 위해 개인적으로 상황에 관계없이 항상 ()를 사용하는 것이 좋습니다.


@ JohannesSchaub-litb C 표준위원회가 C90 표준을 지정했을 때 어떻게 추론했는지에 대한 근거를 제공하지 않는다는 데 동의합니다. 당신은 그들에게 물어봐야 할 것입니다 ... 그것은 아무런 근거없이 대답하지만, C는 구문이 6.5.3에 명시된 것과 같기 때문에 그것을 허용하지 않습니다. OP는 또한 이 답변에서 설명하는 sizeof expression및 의 차이점을 인식하지 못하는 것처럼 보였습니다 sizeof(type).
Lundin

(기록을 위해 방금 C90과 C11의 이론적 근거를 모두 읽었으며 어떠한 설명도 제공하지 않았습니다.)
Lundin

나는 그것에 대한 필요한 근거가 없다고 생각한다. 그것은 원래 C 디자이너들이 그것을하기로 결정한 방식 일 뿐이다. 아마도 그것은 초기 파서의 일을 더 쉽게 만들었습니다. typedef와 변수가 동일한 네임 스페이스를 공유한다는 사실에 대한 답변을 게시하려고했지만 이것이 첫 번째 구문을 허용하는 것을 배제하지는 않습니다. 괄호가 없을 때 변수를 선호하고,있는 경우 유형을 선호하며, 이름이 모호하지 않을 때 두 형식 모두 사용할 수 있다는 구문 분석 규칙이 필요합니다. 변경할 필요가 없기 때문에 표준위원회는 그대로 두었습니다.
Barmar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.