2009-11-11 7 views
27

나는이 SO question을보고 const ints 대 #defines에 대해 생각해 보았고 실제로 컴파일러가이 문제를 처리 할 수없는 이유를 실제로 이해하지 못한다는 것을 깨달았다. 누군가가gcc가 const int를 대문자로 허용하지 않는 이유는 무엇입니까?

error: case label does not reduce to an integer constant 

const int FOO = 10; 

int main(int argc, char** argv) 
{ 
    switch(argc) 
    { 
     case FOO: { printf("foo\n"); } 
     default: { printf("default\n"); } 
    } 
} 

결과 이유를 다음 코드로 되거 수 나는 6.8.4.2.3에 내용의 ISO-C99 사양을 읽어

각각의 경우 레이블 의 표현은 정수 상수 이어야하며 두 개의 경우는 동일하지 않습니다. 동일한 상수 표현 스위치 명령문은 변환 후 동일한 값을 가져야합니다.

나는 왜 그 표현식이 일정해야하는지 이해하지만 왜 리터럴만으로는 컴파일러 (gcc 4.2.1)가 행복하지는 않은지 이해한다.

+0

흥미롭게도 gcc-4.3.4에서 코드가 제대로 컴파일되어 실행되는 것 같습니다. http://ideone.com/n1bmIb 편집 : 아 .. C.가 아니라 C++ 일뿐입니다. – GrahamS

답변

26

기술적으로는 값이 case 문장의 시점에서 컴파일러에 알려졌지만 상수 표현식은 const 한정 유형 값과 동일하지 않습니다.

다른 파일이 extern const int FOO으로 선언되고 같은 방식으로 사용하려고하면 어떻게 될지 상상해보십시오. 컴파일러는 다른 파일에 정의 되었기 때문에 FOO이 무엇인지 알 수 없습니다. 값이 인 경우에도 상수가 이 아닙니다.

+2

Ah. extern 예제를 가져 주셔서 감사합니다. 슈퍼 명확. – nall

+13

'extern' 예제는 아무 것도 명확하게하지 않으며 실제로 아무 것도 설명하지 않습니다. C++ 언어에서는 C와 마찬가지로'extern' 상수를 선언 할 수 있습니다. C++에서는 상수 표현식에서 'const int' 객체를 사용하는 것이 합법입니다 (물론'extern '이 아닌). 최초의 질문에 대한 유일한 진정한 대답은 그것이 역사적으로 그런 식으로 행해졌다는 것입니다. C의 맨 처음부터 "상수"라는 용어는'const' 객체가 아닌 리터럴 수치 값을 의미했습니다. 왜? 으니까. – AnT

+1

글쎄, extern 예제는 내가 컴파일러가 처리 할 수 ​​없다는 것을 생각해 낼 수없는 예제이다. 댓글은 가치가 있습니다. 감사. – nall

관련 문제