21

pragma 指令的范围是什么?例如,如果我说#pragma warning(disable: 4996)在另一个文件 B 中包含的头文件 A 中,这是否也会禁用 B 中的所有这些警告?或者我应该再次启用文件 A 末尾的警告吗?

4

3 回答 3

21

直到翻译单元结束。通俗地说,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"
于 2011-02-22T13:24:45.647 回答
8

编译指示特定于使用的编译器和平台。所以最好的办法是查看编译器的文档。

对于 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 特定的“链接”杂注,它将对某些库的依赖添加到翻译单元及其所有“用户”。

于 2011-02-22T13:25:01.947 回答
1

是的,它还会禁用 B 中的警告。

翻译单元是一个 .cpp 文件,它包含的所有文件都展开成一个大文件。该 pragma 将持续到翻译单元的末尾,或者直到另一个 #pragma 警告更改设置。或者,如果您的编译器支持#pragma push 和#pragma pop,它将持续到下一个#pragma pop。

'#pragma push' 和 '#pragma pop' 允许您创建范围。此类范围内的#pragma 警告将适用于范围的末尾。

于 2011-02-22T13:27:08.377 回答