2012-09-18 3 views
7

다음 코드는 나에게 잘 보이는 :C2070 - 불법를 sizeof 피연산자

#include <stdio.h> 

    template <typename T> 
    struct A 
    { 
     static float m_kA[]; 
    }; 

    template <typename T> 
    float A<T>::m_kA[] = {1.0f, 2.0f, 3.0f}; 

    int main() 
    { 
     printf("%d\n", 
      sizeof(A<unsigned int>::m_kA)/
      sizeof(A<unsigned int>::m_kA[0])); 
     return 0; 
    } 

하지만 난 VC9로 컴파일 할 때 나는 다음과 같은 오류를

error C2070: 'float []': illegal sizeof operand 

를 얻을 나는이 코드를 컴파일 할 것으로 예상한다. 내가 놓친 게 있니? 누구든지이 이상한 동작을 수정하는 방법을 알고 있습니까 (서식 파일을 사용하지 않고 똑같은 작업을하면 잘 컴파일되고 출력됩니다).

템플릿을 제거하는 옵션이 아니라는 것을 유의하십시오.이 예제를 사용하면 템플릿에 배열이 포함 된 형식이 필요한 코드에서 발생하는 문제를 재현 할 수 있습니다.

감사

+1

FWIW, GCC 4.7.1에서 잘 컴파일 : http://liveworkspace.org/code/19f48dbdb07463b08a310c168ab59a67. 그것이 또 다른 MSVC 버그 또는 뭔가인지 조심하십시오. – chris

+0

나는 계산식이 계산식이라고 생각하지 않는다. – Nobody

+4

@Nobody'sizeof array/sizeof array [0]'은 배열의 길이를 계산하는 일반적인 관용구입니다.당신이 생각하기에 그것은 무엇이라고 생각합니까? 아니면 다른 사람들이 생각한다고 생각합니까? – hvd

답변

4

그것은 잘 정의입니다. 클래스 정의에서 m_kAfloat[] 유형으로 선언됩니다.이 유형은 불완전한 유형이며 sizeof과 함께 사용할 수 없습니다. m_kA의 정의에서 float[3] 유형으로 다시 선언 된 후 sizeof을 사용해도됩니다. (8.3.4 어레이 선언의 의미에 적용).

3.4.6에서와 스페이스 별명 [basic.lookup.udir] - 지시어 사용 : 모든 형태의 조정 후

10 (이 동안의 typedef (7.1.3)은 그 정의로 대체 됨), 주어진 변수 또는 함수를 참조하는 모든 선언에 의해 지정된 유형은 동일해야한다. 단, 배열 객체에 대한 선언은 주요 객체의 존재 여부에 따라 다른 배열 유형을 지정할 수있다 배열 경계 (8.3.4). 유형 식별에 대한이 규칙을 위반하더라도 진단은 필요하지 않습니다. 3.9.2 화합물의 종류 [basic.compound]에서

:

6 ...] 배열 객체의 선언 타입은 알려지지 않은 크기의 배열에 따라서 하나 불완전 할 수도 번역 단위를 가리키고 나중에 완료하십시오. 그 두 점 ("T의 미지의 배열"과 "N의 배열"의 배열)에있는 배열 유형은 다른 유형입니다. [...]

컴파일러 문제를 해결하려면 m_kA을 완전 유형으로 선언해야합니다. 크기를 지닌 다른 고정 회원도 도움이 될 수 있습니다.

[C++ 11에서 인용 한 내용이지만 C++ 03은 동일한 규칙을 따랐습니다. ]

+1

C++에서 초기화를 인라인 할 수 있다면 매우 기쁠 것입니다. 문제는 내가 아는 한 내가 할 수있는 일은 로컬 변수 나 전역 변수에 대해서만 할 수 있다는 것입니다. 따라서 템플릿을 만들 수는 없습니다. 또한 전에 VC9를 정당화하기가 어려웠다 고 말한 적이 있습니다. 템플릿 만 제거하면 모든 것이 작동하기 때문입니다. – valerio

+1

좀 더 생각해 보면, [this] (http://pastebin.com/tumC3NBU) (참고 : 유효한 C++이 아닙니다)와 같은 구조는 형식이 * float가 아닌 'float []'로 남아 있어야하는 합법적 인 이유입니다 [3]'템플릿. 그러나 지금 삭제 된 토론에서 보았 듯이 타입은 실제로'float [3] '입니다. – hvd