你用#pragma 编写了哪些代码,你觉得有用?

2022-01-17 00:00:00 compiler-construction c++ pragma

当 #pragma once 的需要-guard">#ifndef #define #endif 始终有效.

I've never understood the need of #pragma once when #ifndef #define #endif always works.

我已经看到使用 #pragma comment 来链接其他文件,但是使用 IDE 设置编译器设置更容易.

I've seen the usage of #pragma comment to link with other files, but setting up the compiler settings was easier with an IDE.

#pragma 还有哪些其他有用但不广为人知的用法?

What are some other usages of #pragma that is useful, but not widely known?

我不是只是在#pragma 指令列表之后.或许我应该重新表述一下这个问题:

I'm not just after a list of #pragma directives. Perhaps I should rephrase this question a bit more:

您使用 #pragma 编写的哪些代码对您有用?

What code have you written with #pragma you found useful?

.

答案一目了然:

感谢所有回答和/或评论的人.以下是我认为有用的一些输入的摘要:

Thanks to all who answered and/or commented. Here's a summary of some inputs I found useful:

  • Jason 建议使用 #pragma once#ifndef #define #endif 将允许在大型系统上更快地编译.Steve 加入并支持这一点.
  • 280Z28 走在前面,提到 #pragma once 是 MSVC 的首选,而 GCC 编译器则针对 #ifndef #define #endif 进行了优化.因此,一个人应该使用其中之一,而不是两者.
  • Jason 还提到了 #pragma pack 以实现二进制兼容性,而 Clifford 反对这一点,因为可能存在可移植性和字节序问题.Evan 提供了一个示例代码,Dennis 告知大多数编译器将强制填充对齐.
  • sblom 建议使用 #pragma warning 来隔离真正的问题,并禁用已经审查过的警告.
  • Evan 建议使用 #pragma comment(lib, header) 在项目之间轻松移植,而无需重新设置 IDE.当然,这不太便携.
  • sbi 为 VC 用户提供了一个漂亮的 #pragma message 技巧来输出带有行号信息的消息.James 更进一步,允许 errorwarning 匹配 MSVC 的消息,并将适当地显示,例如错误列表.
  • Chris 提供了 #pragma region 以便能够在 MSVC 中折叠带有自定义消息的代码.
  • Jason suggested that using #pragma once or #ifndef #define #endif would allow faster compiling on a large-scale system. Steve jumped in and supported this.
  • 280Z28 stepped ahead and mentioned that #pragma once is preferred for MSVC, while GCC compiler is optimised for #ifndef #define #endif. Therefore one should use either, not both.
  • Jason also mentioned about #pragma pack for binary compatibility, and Clifford is against this, due to possible issues of portability and endianness. Evan provided an example code, and Dennis informed that most compilers will enforce padding for alignment.
  • sblom suggested using #pragma warning to isolate the real problems, and disable the warnings that have already been reviewed.
  • Evan suggested using #pragma comment(lib, header) for easy porting between projects without re-setting up your IDE again. Of course, this is not too portable.
  • sbi provided a nifty #pragma message trick for VC users to output messages with line number information. James took one step further and allows error or warning to match MSVC's messages, and will show up appropriately such as the Error List.
  • Chris provided #pragma region to be able to collapse code with custom message in MSVC.

哇,等一下,如果我想发布关于不的帖子,除非有必要,否则怎么办?

Whoa, wait, what if I want to post about not using #pragmas unless necessary?

  • Clifford 从另一个角度发布了关于不 使用#pragma.赞.
  • Clifford posted from another point of view about not to use #pragma. Kudos.

如果 SOers 有发布答案的冲动,我会在此列表中添加更多内容.谢谢大家!

I will add more to this list if the SOers feel the urge to post an answer. Thanks everyone!

推荐答案

每个 pragma 都有其用途,否则它们一开始就不会存在.

Every pragma has its uses, or they wouldn't be there in the first place.

如果您知道不会将代码移植到不同的编译器,则编译指示once"只是更少的输入和更整洁.它也应该更有效,因为编译器根本不需要解析头来确定是否包含其内容.

pragma "once" is simply less typing and tidier, if you know you won't be porting the code to a different compiler. It should be more efficient as well, as the compiler will not need to parse the header at all to determine whether or not to include its contents.

回答评论:假设您有一个 200kB 的头文件.使用once",编译器会加载一次,然后知道它在下次看到它引用时根本不需要包含头文件.使用#if,它每次都必须加载和解析整个文件以确定所有代码都被if禁用,因为每次都必须评估if.在大型代码库上,这可能会产生重大影响,尽管实际上(尤其是预编译头文件)可能不会.

edit: To answer the comments: imagine you have a 200kB header file. With "once", the compiler loads this once and then knows that it does not need to include the header at all the next time it sees it referenced. With #if it has to load and parse the entire file every time to determine that all of the code is disabled by the if, because the if must be evaluated each time. On a large codebase this could make a significant difference, although in practical terms (especially with precompiled headers) it may not.

当您需要结构的二进制兼容性时,pragma "pack" 非常有用.

pragma "pack" is invaluable when you need binary compatibility for structs.

对于二进制格式,您提供的字节必须与所需格式完全匹配 - 如果您的编译器添加了一些填充,它将搞砸数据对齐并破坏数据.因此,对于您希望传递给/从操作系统调用或 TCP 数据包的二进制文件格式或内存结构的序列化,使用直接映射到二进制格式的结构比成员序列化"更有效(逐个编写字段)- 它使用的代码更少,运行速度更快(在嵌入式应用程序中必不可少,即使在今天也是如此).

pragma "error" 和 "message" 非常方便,尤其是在条件编译块中(例如,错误:'Release for ePhone' 构建未实现",消息:在此构建中启用了额外的调试和分析代码")

pragma "error" and "message" are very handy, especially inside conditional compliation blocks (e.g. "error: The 'Release for ePhone' build is unimplemented", message: "extra debugging and profiling code is enabled in this build")

pragma "warning"(尤其是使用 push & pop)对于暂时禁用烦人的警告非常有用,尤其是在包含编写不佳的第三方标头(充满警告)时 - 特别是在您使用警告级别 4 构建时.

pragma "warning" (especially with push & pop) is very useful for temporarily disabling annoying warnings, especially when including poorly written third-party headers (that are full of warnings) - especially if you build with warning level 4.

edit:好的做法是在构建中实现零警告,这样当警告发生时你会注意到它并立即修复它.您当然应该在自己的代码中修复所有警告.但是,有些警告根本无法修复,并且不会告诉您任何重要的信息.此外,在使用第三方库时,您无法更改其代码以修复警告,您可以通过禁用库的警告从构建中删除垃圾邮件".使用 push/pop 允许您仅在库包含期间有选择地禁用警告,以便编译器仍然检查您自己的代码.

edit: Good practice is to achieve zero warnings in the build so that when a warning occurs you notice it and fix it immediately. You should of course fix all warnings in your own code. However, some warnings simply cannot be fixed, and do not tell you anything important. Additionally, when using third party libraries, where you cannot change their code to fix the warnings, you can remove the 'spam' from your builds by disabling the library's warnings. Using push/pop allows you to selectively disable the warnings only during the library includes, so that your own code is still checked by the compiler.

相关文章