【问题标题】:Preprocessor directive in middle of c++ function?c++函数中间的预处理器指令?
【发布时间】:2021-06-22 16:31:35
【问题描述】:
void VoxelTerrain::set_stream(Ref<VoxelStream> p_stream) {
    if (p_stream == _stream) {
        return;
    }

    _stream = p_stream;

#ifdef TOOLS_ENABLED
    if (_stream.is_valid()) {
        if (Engine::get_singleton()->is_editor_hint()) {
            Ref<Script> script = _stream->get_script();
            if (script.is_valid()) {
                // Safety check. It's too easy to break threads by making a script reload.
                // You can turn it back on, but be careful.
                _run_stream_in_editor = false;
                _change_notify();
            }
        }
    }
#endif

    _on_stream_params_changed();
}

上述函数中的#ifdef 什么时候执行?我认为 # 表示在实际代码之前执行的预处理器指令。然而在这段代码中,预处理器的东西似乎引用了一个只能在编译和执行后实例化的实际对象?

【问题讨论】:

  • 如果TOOLS_ENABLED 被定义,那么就好像代码部分(#ifdef#endif)不存在。
  • 你要找的术语是条件编译。
  • 我的代码看起来有点像int array[] = { #include "data.csv" };
  • 预处理器不关心内容。在这种情况下,稍后出现的编译步骤要么看到 #ifdef#endif 之间的代码,要么看不到,这取决于预处理器是否知道预处理器符号 TOOLS_ENABLED 的定义。您甚至可以对此更加疯狂,并且编译器不会抱怨void foo() { std::cout &lt;&lt; "foo\n"; #ifdef BAR } void bar() {std::cout &lt;&lt; "bar\n"; #endif }(当然需要添加换行符)
  • Fabian 关于预处理器不关心的观点在您开始使用宏之后变得非常重要。 #define IDENTIFIER replacement 会导致完全愚蠢的文本替换。无论在哪里找到IDENTIFIER,它都会被replacement 替换,无论替换是多么不合逻辑、疯狂或完全愚蠢。使用宏要非常小心。

标签: c++ c-preprocessor


【解决方案1】:

上述函数中的#ifdef什么时候执行?

它在“编译器”看到代码之前执行。如果预处理器知道TOOLS_ENABLED 符号是什么,那么预处理器会继续将此代码传递给编译器。

如果预处理器不知道TOOLS_ENABLED 是什么,那么它将跳过这块代码,并且不将该代码传递给编译器。

这是一个常见的技巧,通常允许“调试”构建执行一堆额外的验证以确认没有发生错误,但从“发布”构建中消除所有这些缓慢的双重检查,以便它们运行得非常快。

【讨论】:

    猜你喜欢
    • 2017-09-27
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多