【发布时间】:2026-01-15 21:15:02
【问题描述】:
我正在 boost::spirit::x3 之上使用 C++ 开发一个重要的解析器。我将我的解析代码拆分为逻辑单元,其中一些是相互依赖的。例如,一个单元是一个表达式解析器,它也公开了一个标识符解析器。目标语言的许多更高级别的句法结构包括表达式和标识符,因此该单元通常是依赖项。我已将代码分成三份文件as the documentation recommends。如果有单位 foo、bar 和 quux,我有如下文件:
parser
foo.h
foo_def.h
foo.cpp
bar.h
bar_def.h
bar.cpp
quux.h
quux_def.h
quux.cpp
.h 扩展 BOOST_SPIRIT_DECLARE 的位置; _def.h 扩展 BOOST_SPIRIT_DEFINE,.cpp 扩展 BOOST_SPIRIT_INSTANTIATE。我遇到了一个持久性问题,由于 Spirit 代码中的静态初始化失败(.../x3/nonterminal/rule.hpp 的第 160 行),我的代码在启动时出错,但仅在运行调试版本时。
基于this one 和this one 之类的* 问题和答案,加上在发布配置中构建时代码执行没有错误的事实,我相信我的代码没有任何问题。如果无法在调试中修复我的代码,我可以看到两种解决方法:
仅在调试版本中使用编译指示声明来更改静态初始化的顺序。 (更改 .vcxproj 文件中项目的顺序不会影响初始化顺序)在 Visual Studio 中,如果我将
#pragma init_seg(lib)放在表达式解析器的 .cpp 文件中,问题就会消失。-
仅在调试版本中在必要时包含多余的
_def.h文件,例如如果 quux 依赖于上面的 bar 则在quux.cpp中包含bar_def.h将解决问题,但会破坏将解析器拆分为多个文件的目的。
我想知道这个问题的一般状态是什么?这似乎是一个已知问题,但已经存在了很长时间,所以我不应该指望它会在精神层面上解决?有没有更好的方法来构造我的代码以使这个问题不会发生?我想知道是否有可能,例如,将所有解析器及其子解析器创建为第一次使用时创建的函数范围内的静态变量,但文献中没有这样的例子,所以我不确定这是否可能?
【问题讨论】:
标签: c++ boost boost-spirit boost-spirit-x3