2015-01-11 2 views
15

나는대로 컴파일 대 'C'로 컴파일 사이에 다음과 같은 차이가있어 'C++' C의 함수에서 {0}을 (를) 반환 하시겠습니까?

struct A { 
    int x; 
    int y; 
}; 

struct A get() { 
    return {0};  
} 

모든 것을 잘 간다 'C++'로 컴파일 할 때. 그러나 'C'로 컴파일 할 때; 나는 점점 오전 :

오류 : 예상 발현 내가 수행하여 해결할 수

: 차이가 어디에서 오는

return (struct A){0};  

그러나, 나는 궁금하다. 이 차이점이있는 언어 참조를 가리킬 수 있습니까?

+0

나는 C++ 컴파일러가 자동으로 반환 값을'struct A'로 변환한다고 가정합니다. 그리고 c = +에서'struct A get()'그냥'A get()'을 쓸 필요가 없습니다. –

+1

무엇이'(*)'입니까? – Ankur

+4

C++ 컴파일러 * 이전 *에서 C++ 11로 시도 했습니까? [꽤 확신한다] (http://ideone.com/PBFlOR). – WhozCraig

답변

24

두 가지 메커니즘이 완전히 다른 메커니즘을 사용합니다. 그 중 하나는 C++ 11에만 해당되며 다른 하나는 C99에만 해당됩니다.

첫번째 비트

struct A get() { 
    return {0}; 
} 

는 [stmt.return]에 따라 (6.6.3 (2))에

(...)를 말한다 C++ 11 braced-init-list이있는 return 문은 지정된 초기화 목록에서 copy-list-initialization에 의해 함수에서 반환 될 객체 또는 참조를 초기화합니다. [예 :

std::pair<std::string,int> f(const char *p, int x) { 
    return {p,x}; 
} 

-단부 예]

이 통로 (C++ 11 전이나 C++) C에 존재하지 않으므로 C 컴파일러는 그것을 처리 할 수있다. 한편

,

struct A get() { 
    return (struct A){0}; 
} 

는 일부 C++ 컴파일러, 특히 GCC는 언어 확장으로 제공하지만 (C++에 존재하지 않는 "복합 리터럴"라는 C99 기능을 사용, GCC는 대한 경고 그것과 함께 -). 의미는 C99 표준의 섹션 6.5.2.5에 자세히 설명되어 있습니다. 돈 인용 이니셜의 걸림쇠 둘러싸인 목록 뒤에 괄호 형명 구성

4 후위식이 화합물 리터이다. 값이 이니셜 라이저 목록에서 제공되는 이름이없는 객체를 제공합니다. (각주 80)

80)이 표현식은 캐스트 표현식과 다릅니다. 예를 들어 형 변환은 스칼라 유형 또는 void으로의 변환 만 지정하고 캐스트 표현식의 결과는 좌변 값이 아닙니다.

따라서이 경우 (struct A){0}은 반환 값으로 복사되어 반환되는 명명되지 않은 개체입니다. (현대 컴파일러는이 복사본을 삭제할 것이므로 런타임 오버 헤드를 두려워 할 필요가 없습니다.)

그리고 거기에 장과 절이 있습니다.왜 이러한 기능이 각자의 언어로 된 방식으로 존재하는지는 매혹적인 토론이 될 수 있지만 각 표준위원회 외부의 모든 사람이 질문에 대한 권위있는 대답을하는 것이 어렵다는 것을 두려워합니다. 두 기능은 C 및 C++ 분할 방식 이후에 도입되었으며 나란히 개발되지도 않았습니다. 작은 일이라도 발산은 불가피합니다.

+0

잘 설명 된 설명. 덕분에 – sramij

+0

BTW, 실제로'(구조체 A) {0}'이 (가) 돌아오고 있습니까? AFAIK,'return' 문은'(struct A) {0, 0}'이어야합니다. – haccks

+1

@hackks : braced 초기화 목록에 언급되지 않은 내용은 0으로 초기화됩니다 (C99의 6.7.8 (21) 참조). 이것은 일반 구조체 및 배열 초기화에서도 발생합니다. – Wintermute

관련 문제