2013-11-29 1 views
2

문제가있는 곳을 이해합니다. 왜 gcc에서 오류 출력이 나지 않는지 잘 모르겠습니다. 문제를 발생 문제gcc 4.7.3 생성자와 함께 make_shared를 사용할 때의 내부 컴파일러 오류

의 선은 다음과 같습니다

std::string type,rel,pred; 
std::tie(type, rel, pred) = tuple; 
auto supertype = std::make_shared<Node>(Token(type)); // This 
auto predicate = std::make_shared<Node>(Token(pred)); // and this 

참고로, 노드의 ctor는 다음과 같습니다

auto type_token = Token(type); 
auto pred_token = Token(pred); 
auto supertype = std::make_shared<Node>(type_token); 
auto predicate = std::make_shared<Node>(pred_token); 
:

Node (Token & token) 

내가 이렇게하면, 나는 오류를 얻을

내 GCC :

posix gcc version 4.7.3 (Debian 4.7.3-8)

,

실제 오류는 다음과 같습니다

> Internal compiler error: Error reporting routines re-entered. Please 
> submit a full bug report, with preprocessed source if appropriate. See 
> <file:///usr/share/doc/gcc-4.7/README.Bugs> for instructions. 

충분히 재미있게,이 디렉토리는 위의도 존재하지 않습니다.

make_shared 생성자 내에서 객체를 구성하는 것이 잘못된 이유는 무엇입니까?

답변

3

임시 개체는 비 const 왼쪽 값 참조에 바인딩 할 수 없습니다. 따라서 지정된 Node 생성자로 전달할 수 없습니다. 컴파일러는 거부해야합니다

Node node1(Token(type)); 
Node node2(Token(pred)); 

같은 당신의 코드를 내부적으로 동일한 초기화를 수행 할 std::make_shared을 얻으려고 노력 마찬가지입니다 : 당신이 그 임시 개체를 전달할 수 make_shared를 얻기 위해 노력하고있다

auto supertype = std::make_shared<Node>(Token(type)); 
auto predicate = std::make_shared<Node>(Token(pred)); 

const 왼쪽 값 생성자. 컴파일러는 프로그램을 부적절한 것으로 진단하고 컴파일하지 못하게해야합니다. 이는 ICE로 충돌하는 것과 똑같은 것은 아니며 항상 컴파일러 버그를 나타냅니다. 당신이 제안으로

해결해야 할 중 당신의 "하지만이 작업 수행"코드 - make_shared에 좌변 참조를 전달 - 또는를 rvalue 참조 Node에 대한 생성자 작성 :

Node(Token&&); 

편집 : 내 생각을 이것은 GCC bug# 56869이며 4.6.4 및 4.7.4에서 수정 된 것으로 보이며 2013-11-18에 폐쇄되었습니다. 이 글을 읽는 사람이 4.7.4에서이 테스트 케이스를 쉽게 실행할 수 있다면 :

#include <memory> 
#include <string> 

struct Token { 
    Token(std::string lex); 
}; 

struct Node { 
    Node(Token& token); 
}; 

int main() { 
    auto supertype = std::make_shared<Node>(Token{"foo"}); 
    auto predicate = std::make_shared<Node>(Token{"bar"}); 
} 

결과를 코멘트에 게시하시기 바랍니다.

+0

대답은 Ty입니다. 호기심에서 벗어난이 임시 객체는 ^^ ** ​​할당 된 객체가 아닙니다 **. std :: make_shared (새 토큰 (foo)). 생성자가 포인터를 허용한다고 가정합니다. http://coliru.stacked-crooked.com/a/f94c856dd5f3800b –

+0

GCC 4.8은이 프로그램을 올바르게 컴파일하고 [많은 오류 메시지를 내뿜습니다.] (http://coliru.stacked-crooked.com/a/777204dbaf03dc45) – Casey

+1

@Alex rvalues는 임시 변수, 함수 반환 값 및 lvalue의'std :: move (...) '결과에 해당합니다. 포인터가 괜찮을거야. – Casey

관련 문제