且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

分裂后增强精神x3的奇怪语义行为

更新时间:2023-11-12 21:39:16

我已经找到了导致错误的原因.

I've found the cause of the bug.

该错误是因为Expect指令按值将其作为主题解析器,这是在parser::impl::identifier初始化程序运行之前进行的.

The bug is with the fact that the expect directive takes it subject parser by value, which is before the parser::impl::identifier initializer runs.

要可视化,请想象在parser::impl::identifier之前运行的parser::impl::enum_parser静态初始化程序.这对于编译器是有效的.

To visualize, imagine the static initializer for parser::impl::enum_parser running before parser::impl::identifier. This is valid for a compiler to do.

因此,副本具有未初始化的name字段,一旦期望点尝试使用which_成员构造x3::expectation_failure,该字段就会失败,因为从nullptr构造std::string是非法的.

The copy, therefore, has an uninitialized name field, which fails as soon as the expectation point tries to construct the x3::expectation_failure with the which_ member, because constructing a std::string from a nullptr is illegal.

总而言之,我担心这里的根本原因是静态初始化顺序惨败.我将查看我是否可以解决该问题并提交PR.

All in all, I fear the root cause here is Static Initialization Order Fiasco. I'll see whether I can fix it and submit a PR.

一种直接的解决方法是按相反的顺序列出源文件的顺序,以便在定义后使用:

An immediate workaround is to list the order of the source files in reverse, so that use comes after definition:

set(SOURCE_FILES 
    identifier.cpp
    enum.cpp 
    main.cpp 
)

请注意,如果这可以在实现定义的编译器上(在我的软件上)修复,则可以.该标准未指定跨编译单元的静态初始化的顺序.

Note that if this fixes it on your compiler (it does on mine) that is implementation defined. The standard does NOT specify the order of static initialization across compilation units.