gcc 4.7.3与构造函数一起使用make_shared时出现内部编译器错误

gcc 4.7.3 internal compiler error when using make_shared with a constructor

本文关键字:shared 错误 编译器 内部 make 构造函数 一起 gcc      更新时间:2023-10-16

我知道问题出在哪里,只是不确定为什么我没有从gcc得到任何错误输出。

产生问题的问题行是:

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为:

Node ( Token & token )

如果我这样做,我不会出错:

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 );

我的GCC是:

posix gcc版本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构造函数中构造对象有什么问题?

临时对象不能绑定到非const左值引用。因此,不能将一个传递给指定的Node构造函数。编译器应拒绝:
Node node1(Token(type));
Node node2(Token(pred));

尝试让std::make_shared在内部使用您的代码执行相同的初始化也是如此:

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

您正试图让make_shared将该临时对象传递给非const左值构造函数。编译器应该将程序诊断为格式错误并编译失败。这与ICE崩溃不同,ICE总是指示编译器存在错误。

变通方法是按照你在"但这确实有效"代码中的建议进行——将左值引用传递给make_shared——或者为Node:编写右值引用构造函数

Node(Token&&);

编辑:我认为这是GCC错误#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"});
}

请将结果发表在评论中。