| 编译时配置 | ![]() |
![]() |
![]() |
C++ 预处理器迭代器库可以通过在编译时指定不同的预处理器常量,来配置不同的附加功能。下表描述了可能的预处理器常量。
| 库配置可能的 预处理器常量摘要 |
|
BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE |
支持 #warning 指令 |
BOOST_WAVE_SUPPORT_MS_EXTENSIONS |
支持多种微软特有的语言扩展(即__int8等等) |
BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY |
启用对 #error 和 #warning 指令消息体的预处理。 |
BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES |
如果已定义,则 #pragma 指令将作为记号序列(token sequence)返回给调用者;如果未定义,则跳过整个 #pragma 指令。 |
BOOST_WAVE_PREPROCESS_PRAGMA_BODY |
启用对所有 #pragma 指令体的预处理。 |
BOOST_WAVE_ENABLE_COMMANDLINE_MACROS |
启用使用命令行语法(-DMACRO(x)=definition)定义宏所需的功能 |
BOOST_WAVE_STRINGTYPE |
由Wave库生成的记号(token)包含记号数据以及在输入流中发现该记号的文件位置。 |
BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS |
如果已定义,则预处理器库支持变长参数(variadics)和占位符(placemarkers)。注意,为了支持 C99 模式,也必须定义此常量。 |
BOOST_WAVE_SUPPORT_CPP0X |
如果已定义,则预处理器库支持 C++0x 关键字和 C++0x 特有功能,如变长参数、占位符、扩展字符和字符串字面量。这隐含了对 |
BOOST_WAVE_SUPPORT_CPP1Z |
如果已定义,则预处理器库支持 C++17 关键字——目前仅为 |
BOOST_WAVE_SUPPORT_CPP2A |
如果已定义,则预处理器库支持 C++20 关键字,特别是 |
BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH |
如果已定义,它将确定支持的初始最大可能包含文件嵌套深度。默认值为 1024。 |
BOOST_WAVE_SUPPORT_PRAGMA_ONCE |
如果已定义,则支持 |
BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE |
如果已定义,则支持 |
BOOST_WAVE_SUPPORT_INCLUDE_NEXT |
如果已定义,则支持 |
BOOST_WAVE_USE_STRICT_LEXER |
如果将其定义为非 0 值,则 C/C++ 词法分析器将识别严格的 C99/C++ 基本源字符集。如果未定义或定义为零,则词法分析器会将 '$' 字符识别为标识符的一部分。 |
BOOST_WAVE_PRAGMA_KEYWORD |
如果将其定义为字符串字面量,它将用作库识别为特定 Wave pragma 的 pragma 关键字。此常量默认为 "wave",即库识别所有 #pragma wave option [(argument)] 指令,并将处理调度给 interpret_pragma() 预处理钩子函数(见:Preprocessing Hooks)。pragma 的参数部分是可选的。 |
BOOST_WAVE_SUPPORT_LONGLONG_INTEGER_LITERALS |
C++ 标准要求预处理器对整数字面量使用以下类型之一: 仅当您的目标平台支持 long long 整数(定义了 |
BOOST_WAVE_SUPPORT_THREADING |
此预处理器常量允许配置 Wave 库在构建时是否启用多线程支持。如果需要禁用多线程,应将此值(如果已定义)设置为零 ('0');如果要显式启用多线程,应将其设置为不等于零的数值。 如果未定义此常量,Wave 库将使用从 Boost 构建环境中提取的多线程设置进行构建(参见 Boost 配置文档中的 |
可以在使用您自己的记号和/或词法分析器类型的同时使用Wave库。这可以通过在实例化boost::wave::context<>对象时提供您的词法分析器类型作为第二个模板参数来实现。库使用的记号类型派生自定义的公共类型定义由词法分析器类型提供的 typedef。如果您只想提供自己的记号类型,可以使用boost::wave::lex_iterator<>库中包含的类型。该类型需要以要使用的记号类型作为参数。
该Wave库包含几个说明这些可能性的示例。cpp_tokens示例展示了自定义词法分析器和自定义记号类型的用法。所使用的词法分析器类型在功能上完全兼容于默认使用的基于re2c [3] 的词法分析器。它是基于由 Dan Nuffer 编写的SLex [5] 词法分析器示例实现的。其中使用的记号类型在功能上等同于默认记号类型,只是增加了一个额外的operator<<用于转储记号携带的信息。
该WaveC++ 预处理器迭代器库几乎完全作为仅头文件库构建(除了基于 re2c 的词法分析器)。如果您尝试一次性包含所有必需的文件,您会发现生成的编译时间非常长(取决于您的系统配置,可能长达一小时)。这种直接的方法我们称之为包含编译模型。如果您不关心编译时间,这就是可行的方法,不需要特殊处理。
如果您有兴趣缩短编译时间,则应使用以下方法。我们将其称为分离编译模型。诀窍是将不同的对象分开,使它们可以分别编译。将实例化相关模板对象的函数分解出来,使其定义仅对一个编译单元可见。为了进一步简化,此创建函数被包装在一个小的生成器模板结构中。
实现了两个层次的分离:C++ 词法分析器编译的分离以及所使用的不同 Spirit 语法编译的分离。要使用这些分离,您必须在编译整个应用程序时定义两个预处理器常量,并且必须显式实例化一些辅助模板。下表详细列出了这些常量。
| 启用分离编译模型可能需要的 编译常量摘要 |
|
| 分离项 |
|
C++ 词法分析器 |
|
Spirit 语法 |
|
下表显示了如果要使用分离编译模型所需的显式模板实例化。其中的TokenT占位符类型必须替换为您要使用的记号类型,而 LexIteratorT 占位符类型必须替换为您在实例化boost::wave::context<>对象时使用的词法迭代器类型。如果将这些分别放入单独的编译单元中,您将获得最佳效果。其中的IteratorT占位符应替换为用于实例化boost::wave::context<>对象中的边描述符。
| 使用分离编译模型时 所需的显式模板实例化摘要 |
|
| 分离项 |
|
C++ 词法分析器 |
template cpplexer::re2clex::new_lexer_gen<IteratorT>; |
Spirit 语法 |
|
要查看这方面的示例,您可以查看Wave作为 C++ 预处理器迭代器库附带示例包含的驱动程序。相应的文件命名显然为 "instantiate_...something.cpp",其中 '...somthing' 是一个提示,说明内部显式实例化了哪些语法。通过使用分离模型,构建Wave示例所需的编译时间减少了多达 90%。
从 1.77 版本开始,Wave 将要求使用 C++11 特性进行构建,并且将不再支持旧编译器。然而,Wave 将无限期地继续模拟旧预处理器的特性。
![]() |
![]() |
版权所有 © 2003-2011 Hartmut Kaiser
根据 Boost Software License, Version 1.0 分发。(参见附带的 LICENSE_1_0.txt 文件或访问 https://boost.ac.cn/LICENSE_1_0.txt 副本)
最后更新日期2011年1月9日 星期日 16:16