2015-02-01 3 views
2

나는 모든 것을 읽고 사방 대해 C에 "시간 상수를 컴파일 할"수 있고, 나는 아직에 설명을 드릴 수 없습니다 다음C 배열 요소는 실제로 const가 아닙니다.

const short testArray[2]={1,2}; 
//void IndeedConst(void){ testArray[0]=3; } //correctly reports "error: assignment of read-only location 'testArray[0]'" 
const short testItem=testArray[0]; //why "error: initializer element is not constant"?? 

그래서 컴파일러는 testArray [0] 읽기 전용되는 것을 불평/const 그리고 동시에 testArray [0]이 일정하지 않다는 것을 나타냅니다! 나 자신이 컴파일시에 "분명 역 참조 연산자 [] 작동하지 않을 수 있습니다"대답 않았다 "일정 초기화,이 선은 오류없이 컴파일 것 whyever?

const short* testItem=&(testArray[1]); 

을 여기 나는의 주소를 얻고 있습니다 배열의 두번째 항목. 그러므로 일정한 초기화 수있는 문제없이 역 참조!
이에 대한 설명 무엇 ? 정적 저장 기간과 변수의

+1

'const short testItem = testArray [0];'은 오류를 생성해서는 안됩니다. MCVE를 게시하십시오. – juanchopanza

+0

@mafso c89, c99 또는 c11 모드의 clang 3.5는 지원되지 않습니다. 유사하게 [gcc와] (http://ideone.com/gWHhkw). 어떤 컴파일러와 C 표준을 컴파일하고 있습니까? – juanchopanza

+0

@mafso 명확히하기 : 나는 이것이 C라는 것을 알고있다. 나는 C++에 관해서 아무 말도하지 않았다. – juanchopanza

답변

4

이, 이니셜 라이저는 상수 식으로 구성해야합니다. 이러한 "컴파일 타임"을 포함 :

  • 산술 상수 표현식 : 정수/열거 형/문자/부동 소수점 수이고 피연산자는 sizeof 수만 있습니다. 다른 변수의 값을 참조하지 않을 수도 있습니다.
  • null 포인터 상수.
  • 정수 상수 표현식에 선택적으로 추가되는 주소 상수. 이 주소 상수는 null이거나 함수를 가리 키거나 정적 저장 기간이있는 객체를 가리킬 수 있습니다. 표준에서는 객체의 값을 참조하지 않는 한 []&과 같은 연산자를 사용할 수 있습니다. 이 경우

, testArray[1] 인해 다른 변수에 저장된 값을 참조로 일정한 표현되지 않지만 &testArray[1]는 어드레스 정수이고 유효한 일정한 표현이다.

참조 : C99 표준, 섹션 6.6.

+0

대단히 고마워,이게 내가 이해 한 것이다. const와 static (매우 직관적이지는 않지만)이지만 이니셜 라이저에는 const 변수 (예 : testArray [0])를 포함 할 수 없다. 두 번째 정의 (& testArray [1])의 [..] 연산자는 & testArray + 1, 즉 '정수 상수 표현식에 선택적으로 추가됨'을 나타 내기 때문에 간단하게 작동합니다. 마침내 무언가를 몇 시간 동안 나에게 걱정스럽게 설명했다, 다시 감사한다! –

+0

그냥 마지막 메모 : 컴파일러 응답 "오류 : 이니셜 라이저 요소가 상수가 아닙니다"생각 완전히 오해의 소지가? 이니셜 라이저 요소는 상수입니다! 요점은 유효한 이니셜 라이저 (const 변수)가 아님을 의미합니다. –

+0

@VittorioG. 혼란 스럽지만 위에서 언급 한 상수 표현을 의미하는 "상수"라는 단어를 사용하고 있습니다. 키워드'const'는 런타임에서 값을 수정할 수없는 것으로 표시하며 "상수"로 간주되지 않습니다. 이 혼란스러운 표현의 이유는 C가 원래 const 키워드를 갖지 않았기 때문에 "상수"의 유일한 의미는 위에서 설명한 바와 같았 기 때문입니다. – interjay