Reputation: 14839
I understand where the problem is, I'm just not sure why am I not getting any error output from gcc.
The lines in question which generate the issue are:
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
FYI, Node Ctor is:
Node ( Token & token )
If I do this, I get no error:
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 );
My GCC is:
posix gcc version 4.7.3 (Debian 4.7.3-8)
The actual error is:
> 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.
Funnily enough, this directory above doesn't even exist.
What's wrong with constructing an object within the make_shared constructor?
Upvotes: 2
Views: 1157
Reputation: 42554
A temporary object cannot bind to a non-const
lvalue reference. You therefore cannot pass one to the specified Node
constructor. The compiler should reject:
Node node1(Token(type));
Node node2(Token(pred));
The same is true for trying to get std::make_shared
to perform the same initialization internally with your code:
auto supertype = std::make_shared<Node>( Token( type ) );
auto predicate = std::make_shared<Node>( Token( pred ) );
You are trying to get make_shared
to pass that temporary object to the non-const
lvalue constructor. The compiler should diagnose the program as ill-formed and fail to compile it. That is notably NOT the same thing as crashing with an ICE, which always indicates a compiler bug.
Workaround is to either do as you suggest in your "but this does work" code - pass an lvalue reference to make_shared
- or to write an rvalue reference constructor for Node
:
Node(Token&&);
EDIT: I think this is GCC bug# 56869 which appears to have been fixed in 4.6.4 and 4.7.4 and was closed on 2013-11-18. If anyone reading this can easily run this testcase in 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"});
}
please post the results in a comment.
Upvotes: 3