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

c++ react to external #define

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

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

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

main.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

我检查了头文件中的 'passing of definitions' 是否有效,方法是打印向量的 大小 ,但是 收到零 这表明编译器没有考虑在 someFile.hpp.

中定义 DEBUG_ENABLED

然后我在 Whosebug 上查看如何对外部文件的定义做出反应,并发现了这个 post:

Is it possible to use #define from other cpp file?

那里接受的答案声称

Defines inside a source file aren't seen by other translation units. Implementation files are compiled separately.

我对这个答案的问题是,我的经验告诉我恰恰相反,因为上面提到的 included glfw 清楚地 对 GLFW_INCLUDE_VULKAN 定义做出了反应我做了。
如何才能实现这种行为(能够对外部源文件中的定义作出反应)?

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

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

main.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();
};

someFile.cpp:

#include <stdio.h>

#include "someFile.hpp"

void Test::doCount() {
    printf("count: %lu", _debugExtensions.size());    
}

编译,并且 运行 这与:

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

表明定义确实得到preprocessor-directives in included header-files 做出相应的反应。 不当行为(正如评论所指出的)是由 header 的不同包含引起的,其中只有一个子集定义了 DEBUG_ENABLED.

这里的例子还是容易出现那个问题!!

(感谢发表评论的人)
一个解决方案有多种可能性:

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