Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
更安全的条件编译? 在MSVC C++程序中,我有一部分代码要根据预处理器定义< /P>启用或禁用。 // 1.h #ifdef MYOPTION //... #endif_C++_Visual Studio_Visual C++_C Preprocessor - Fatal编程技术网

更安全的条件编译? 在MSVC C++程序中,我有一部分代码要根据预处理器定义< /P>启用或禁用。 // 1.h #ifdef MYOPTION //... #endif

更安全的条件编译? 在MSVC C++程序中,我有一部分代码要根据预处理器定义< /P>启用或禁用。 // 1.h #ifdef MYOPTION //... #endif,c++,visual-studio,visual-c++,c-preprocessor,C++,Visual Studio,Visual C++,C Preprocessor,但我发现,在包含在多个编译单元中的.h文件中使用MYOPTION是非常危险的,因为我很容易得到不一致的头(我不想全局定义MYOPTION,因为每次更改它时都需要完全重新编译): 当然,由于包含链式标题,它比这个简化示例复杂得多 有没有一种方法可以避免这种不一致性,例如不费吹灰之力就出现编译时错误 我想做#定义我的选项0或1,但是我必须写一些类似的东西 #if MYOPTION == 1 //... #elif !defined(MYOPTION) #error ... #endif 看起来太复

但我发现,在包含在多个编译单元中的.h文件中使用MYOPTION是非常危险的,因为我很容易得到不一致的头(我不想全局定义MYOPTION,因为每次更改它时都需要完全重新编译):

当然,由于包含链式标题,它比这个简化示例复杂得多

有没有一种方法可以避免这种不一致性,例如不费吹灰之力就出现编译时错误

我想做
#定义我的选项0
1
,但是我必须写一些类似的东西

#if MYOPTION == 1
//...
#elif !defined(MYOPTION)
#error ...
#endif

看起来太复杂了。。。也许有更好的选择

假设您确实需要使用define,最好是通过编译器命令行定义它们,而不是在源文件中使用
#define
。然后,您的
configure
script/makefile/build过程将定义设置一次,您可以保证它将在所有源文件中正确地一致。

基本上,我认为您已经列出了大多数解决方案。我将使用最后一种解决方案,但形式可能略有不同:

#ifndef MYOPTION
#error ...
#endif

...

#if MYOPTION == 1
//...
#endif
因为这个#if MYOPTION==1通常会在每个文件中出现多次。更清楚的是,MYOPTION是该文件的必要条件


你说它“看起来太复杂了”,但恐怕没有比这更“复杂”的解决方案了。

也许你想要的是创建一个单独的配置

您可以转到构建->配置管理器并创建新配置(与调试、发布分开)。创建新配置将允许您定义特定于该配置的预处理器符号

例如,使用名为“MyOption 1”的新配置,可以添加预处理器定义
MyOption=1
。同样的事情也发生在MYOPTION=2,3

每个配置必须单独构建。
调试和发布是单独配置的示例;DEBUG defines
\u DEBUG
和RELEASE defines
NDEBUG

这样做怎么样:让1.h使用不同的选项在obj中定义一个虚拟部分。这样,如果MYOPTION的使用不一致,链接器将发出警告

1.h:

使用a.cpp中定义的MYOPTION而不是b.cpp中定义的MYOPTION进行编译会产生此链接器警告(使用VC 2008):


一致的定义不会产生任何链接器警告。

您不想全局定义
MYOPTION
,但希望其存在是全局一致的?听起来有点矛盾@奥利·查尔斯沃思:我不希望它被全局定义,但我希望在出现错误时出现编译错误,比如在我的
中!已定义
示例。你到底觉得什么是矛盾的?@7vies:如果某个东西需要全局一致,那么定义它的明显位置是全局级别(在依赖定义的所有东西所包含的头文件中,或者在命令行中)。使用相同的代码创建两个项目,一个是全局定义的,一个不是全局定义的?@Oli Charlesworth:我知道,但我不想像我说的那样全局定义它,因为当全局宏更改时,MSVC会重新编译所有内容。我在问题中提到过:我不想全局定义MYOPTION,因为它需要完全重新编译(每次我更改它)@7vies:这个问题在某种程度上是Visual Studio特有的(您确实简要提到过)。许多make系统不会因为makefile更改而重新编译所有目标(这会导致其他问题)。谢谢!我查看了不同的杂注,但没有想到这个选项,看起来很有希望。。。
#ifndef MYOPTION
#error ...
#endif

...

#if MYOPTION == 1
//...
#endif
#ifdef MYOPTION
#pragma section("MYOPTION_GUARD",write)
#else
#pragma section("MYOPTION_GUARD",read)
#endif

namespace { __declspec(allocate("MYOPTION_GUARD")) int MYOPTION_guard; }
b.obj : warning LNK4078: multiple 'MYOPTION_GUARD' sections found with different attributes (40300040)