【发布时间】: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 << "foo\n"; #ifdef BAR } void bar() {std::cout << "bar\n"; #endif }(当然需要添加换行符) -
Fabian 关于预处理器不关心的观点在您开始使用宏之后变得非常重要。
#define IDENTIFIER replacement会导致完全愚蠢的文本替换。无论在哪里找到IDENTIFIER,它都会被replacement替换,无论替换是多么不合逻辑、疯狂或完全愚蠢。使用宏要非常小心。
标签: c++ c-preprocessor