2017-09-08 3 views
0

내가 컴파일하고 맹목적으로 좋아하는 당신은 C로 할 수있는 유연한 배열 구성원 만들려고, 다음과 같은 C++ 코드를 실행 :C++ 구조체 배열 구성원

#include <iostream> 

template <typename T> 
struct Vector { 
    int length; 
    T ts[]; 
}; 

Vector<int> ts = { 
    3, 
    {10, 10, 10}, 
}; 


int main() { 
    std::cout << sizeof(ts) << std::endl; 
    std::cout << ts.data[1] << std::endl; 
    return 0; 
} 

코드는 컴파일을하고 잘 실행되고 C가 동일한 환경에서 출력하는 것과 동일한 결과를 제공합니다 (4와 10을 출력 함).

이제 this answer from 2010에 따르면 유효한 내용이 아니어야합니다. C++. 또한 this wikipedia article에 따르면 "C++에는 유연한 배열 구성원이 없습니다".

제 질문은 위의 코드에서 특히 "T ts[];"이라는 줄에 실제로 어떤 C++ 기능을 사용하고 있습니까? 이 코드는 실제로 내가 일반적으로 생각하는대로 동작합니까, 아니면 정의되지 않은 동작입니까?

+1

그냥 비표준 확장 프로그램입니다. 언어 명세 자체에는 gcc의 구현이 없지만 gcc의 구현은 그렇게합니다. –

+0

컴파일러 확장. 어떤 도구 체인을 사용하고 있습니까? – user4581301

+0

비정상적인 C++ 프로그램에 대한 동작이 정의되었는지 여부를 판단 할 수 있는지 확실하지 않습니다. 표준에 따라 컴파일해서는 안되며, 일부 컴파일러 확장의 경우에는 더 이상 표준에 의존 할 수 없습니다. – Slava

답변

1

C와 C++간에 다른 점 중 하나입니다. A 가변 배열 구성원은 C에서는 유효하지만 C++에서는 유효하지 않습니다.

즉, 많은 현대 컴파일러는 C++의 하위 집합으로 C를 컴파일하여 컴파일러 오류 진단을 토오크 할 때만주의를 기울입니다.

C++ 유연한 배열 구성원을 지원하지 않습니다

데이비드 트리블 그는 특히이 문제를 해결 그의 Incompatibilities Between ISO C and ISO C++ 페이지에서 그것에 순간을 보낸다.

는 (이 기능은 일부 C++ 컴파일러에 의해 확장으로 제공 될 수 있지만, 아마 단지 POD 구조 유형에 대해 유효합니다.)

는 그래서 그래,이 정의되지 않은 동작입니다. 당신이 말했다 개체에 대한 메모리를 할당해야합니다 당신은 또 다른 문제가

template <typename T> 
struct Vector { 
    int length; 
    T ts[1]; 
}; 

: 그런 일을 쓰기 (C와 C++ 모두) 올바른 방법은 그것을 비 제로 차원을 제공하는 것입니다. 단순히 초기화 프로그램을 지정하는 것만으로는 충분하지 않습니다. 그러한 일에 대한 모든 액세스가 존재하는 한, 컴파일러는 최소한 그것이 최소 크기라고 생각합니다.

"range hack" 프로그래머가 범위 한계를 위반하여 C를 사용하여/교란하는 기능을 사용하기 때문에 까다로운 작업을 수행합니다.

이러한 결과는 표준 컨테이너에 저장하거나 값으로 전달할 수 없거나 포인터를 통해 처리하는 것을 피하는 대부분의 작업을 수행 할 수 없다는 것을 포함하여 많은 경우 발생합니다. 그 자리를 차지하고 있지만, 대부분의 유스 케이스에서 C++은 뛰어난 옵션을 가지고 있습니다.