pragma 指令的范围是什么?例如,如果我说#pragma warning(disable: 4996)
在另一个文件 B 中包含的头文件 A 中,这是否也会禁用 B 中的所有这些警告?或者我应该再次启用文件 A 末尾的警告吗?
3 回答
直到翻译单元结束。通俗地说,TU 是源文件及其包含文件。
通常的模式是这样的:
#pragma warning (push) //save
#pragma warning (disable: xxxx)
#pragma warning (disable: yyyy)
...
//code
#pragma warning (pop) //restore prev settings
例如
//A.h
#pragma once
#pragma warning (disable: 1234)
#include "b.h"
//b.h
#pragma once
//when included after a.h 1234 will be disabled
//c.cpp
#include "a.h" //warnings 1234 from b.h is disabled
//d.cpp
#include "b.h" //warnings 1234 from b.h are not disabled
#include "a.h"
编译指示特定于使用的编译器和平台。所以最好的办法是查看编译器的文档。
对于 IBM 编译器,例如:
可以在编译单元的源代码中的任何位置指定许多 pragma 指令;others 必须在任何其他指令或源代码语句之前指定。在每个 pragma 的单独描述中,“使用”部分描述了 pragma 放置的任何限制。
通常,如果您在源程序中的任何代码之前指定 pragma 指令,它适用于整个编译单元,包括包含的任何头文件。对于可以出现在源代码中的任何位置的指令,它从指定的点开始应用,直到编译单元结束。
您可以通过在选定的代码段周围使用互补的 pragma 指令对来进一步限制 pragma 的应用范围。例如,使用 #pragma options source 和 #pragma options nosource 指令如下要求仅将源代码的选定部分包含在编译器列表中:
#pragma options source /* Source code between the source and nosource pragma options is included in the compiler listing */ #pragma options nosource
许多 pragma 提供“pop”或“reset”子选项,允许您以基于堆栈的方式启用和禁用 pragma 设置;这些示例在相关的编译指示描述中提供。
一般来说,pragma 应该在其声明之后立即生效,无论它来自哪个标头,直到翻译单元的末尾。但是,有一些编译指示会影响整个程序。例如,Microsoft 特定的“链接”杂注,它将对某些库的依赖添加到翻译单元及其所有“用户”。
是的,它还会禁用 B 中的警告。
翻译单元是一个 .cpp 文件,它包含的所有文件都展开成一个大文件。该 pragma 将持续到翻译单元的末尾,或者直到另一个 #pragma 警告更改设置。或者,如果您的编译器支持#pragma push 和#pragma pop,它将持续到下一个#pragma pop。
'#pragma push' 和 '#pragma pop' 允许您创建范围。此类范围内的#pragma 警告将适用于范围的末尾。