C++ 对外部 #define 做出反应

c++ react to external #define

本文关键字:对外部 #define C++      更新时间:2023-10-16

glfw3-library可以在包含之前使用定义来包含vulkan:

#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

我想做类似的事情,但对于调试与非调试模式。 我尝试了以下方法:

主.cpp:

#define DEBUG_ENABLED
#include "someFile.hpp"

someFile.hpp:

#ifdef DEBUG_ENABLED
std::vector<const char*> _debugExtensions = {
VK_EXT_DEBUG_UTILS_EXTENSION_NAME
};
#endif
#ifndef DEBUG_ENABLED
std::vector<const char*> _debugExtensions = {};
#endif

我通过打印向量的大小来检查跨头文件的"定义传递"是否有效,但收到零,这表明编译器不考虑在 someFile.hpp 中定义DEBUG_ENABLED。

然后我查看了stackoverflow,看看我如何对extern文件的定义做出反应,并找到了这篇文章:

是否可以使用其他 cpp 文件中的 #define?

那里接受的答案声称

源文件中的定义不会被其他翻译单元看到。实现文件是单独编译的。

我对这个答案的问题是,我的经验告诉我相反的情况,因为上面提到的包含的 glfw显然对我所做的GLFW_INCLUDE_VULKAN定义做出了反应
如何能够实现这种行为(能够对外部源文件中的定义做出反应)?

我被要求创建一个"最小可重现的例子"。
这个例子表明,这个问题确实是我假设的不同问题。
该示例成功地没有重现错误,但它有助于回答我最初问题的一部分。

不要认为这是一个好的解决方案!提供此示例是为了澄清 cpp 的行为,而不是作为在项目中实现的解决方案!

主.cpp:

#define DEBUG_ENABLED
#include "someFile.hpp"
int main() {
Test test = Test();
test.doCount();
return 0;
}

someFile.hpp

#pragma once
#include <vector>
class Test {
public:
#ifdef DEBUG_ENABLED
std::vector<const char*> _debugExtensions = {
"one",
"two"
};
#endif
#ifndef DEBUG_ENABLED
std::vector<const char*> _debugExtensions = {};
#endif
void doCount();
};

一些文件.cpp:

#include <stdio.h>
#include "someFile.hpp"
void Test::doCount() {
printf("count: %lu", _debugExtensions.size());    
}

编译并运行它:

g++ -g main.cpp someFile.cpp -o out
./out

表明定义确实会让包含的头文件中预处理器指令做出相应的反应。 不当行为(如注释所指出的)是由标头的不同含义引起的,其中只有一个子集定义了DEBUG_ENABLED。

这里的例子仍然容易出现这个问题!!

(感谢评论的人)
对于解决方案,有多种可能性:

  1. 使用编译器定义有问题的常量,如下所示:
g++ -DDEBUG_ENABLED
  1. 确保行为依赖于此类常量定义的文件仅从单个翻译单元中包含,或者所有翻译单元在常量定义方面都是一致的。这几乎排除了保留单独的.h(.hpp)和.cpp文件的可能性。