在Visual Studio中定义宏 - 使用/D还是#define?

5
最近,我将一些STL代码移植到VS2008时,想要通过定义新的"_SCL_SECURE_NO_WARNINGS"标志来禁用由"std::copy"生成的警告。 有两种方法可以做到这一点:
- 使用编译器开关"/ D",可以在项目属性中指定。 您需要确保在Release和Debug构建中都定义了它,而我经常忘记这样做。 - 通过在相关STL头文件之前以宏的方式定义它,或者为了完全覆盖,在stdafx.h中定义它: #define _SCL_SECURE_NO_WARNINGS
这两种方法都很好,但我想知道是否有任何支持其中一种方法的理由?
6个回答

10

/D选项通常用于想要在不同的构建中进行不同定义时使用(因此可以在makefile中更改)。

如果您希望始终以相同的方式设置它,请使用#define。


5
将它们放在项目文件中,可以保持平台特定警告和平台之间的紧密关联,这对我来说是正确的做法。
如果它们在代码中,无论是否适用于该平台,它们始终在代码中。您不需要它用于GCC或可能的Visual C++的未来版本。另一方面,通过将其放在代码中,更容易发现它是否存在。如果您移动(复制)代码,将更容易记住将该定义与其一起移动。
每种方法都有优缺点。你的情况可能会有所不同。

2
如果您有一个包含在所有其他文件中的头文件(例如stdafx.h),您应该将其放在那里。编译器命令行开关通常用于构建选项,这些选项并不总是设置,例如NDEBUG,UNICODE等。而您的宏基本上始终会被设置。
这可能听起来很武断。实际上,有些人可能会说其他的事情。最终,您必须决定哪个适合您的情况。

1
一般来说,我更喜欢将 #define 放在代码中,而不是使用 /D 编译器开关,因为查找 #define 比检查编译器设置更直观。

1

/D 不是 msbuild.exe 的有效标志(至少在我使用的版本 v2.0.50727 中不是)。

完成此操作的方式是:

/p:DefineConstants="MY_MACRO1;MY_MACRO2"

这样做的结果是:
Target CoreCompile:
    C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Csc.exe /define:MY_MACRO1;MY_MACRO2 ...

1

如果你在代码中使用它们,请记得适当地进行条件编译:

#ifdef _MSC_VER
#define _SCL_SECURE_NO_WARNINGS
#endif

这将使您的代码具有可移植性。


定义一个符号通常不会在移动到另一个平台时产生影响,即使它没有任何作用。一个简单的注释也同样有效。 - Mark Ransom
在这种情况下,绝对不需要,但在一般情况下,我认为最好将编译器特定的定义放在适当的ifdef / endif对中。 - JesperE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接