Sử dụng từ khóa #pragma trong lập trình

  -  
I"m working on a codebase that is known to only run on windows and be compiled under Visual Studio (it integrates tightly with excel so it"s not going anywhere). I"m wondering if I should go with the traditional include guards or use #pragma once for our code. I would think letting the compiler deal with #pragma once will yield faster compiles and is less error prone when copying and pasting. It is also slightly less ugly ;)

Note: to get the faster compile times we could use Redundant Include Guards but that adds a tight coupling between the included file and the including file. Usually it"s ok because the guard should be based on the file name and would only change if you needed to change in the include name anyways.

Bạn đang xem: Sử dụng từ khóa #pragma trong lập trình


c++ coding-style
Share
Improve this question
Follow
edited Nov 22 "18 at 3:07
*

Jonathan Leffler
684k128128 gold badges841841 silver badges12121212 bronze badges
asked Jul 17 "09 at 15:18
*

Matt PriceMatt Price
40.5k99 gold badges3535 silver badges4343 bronze badges
0
Add a comment |

13 Answers 13


Active Oldest Votes
375
I don"t think it will make a significant difference in compile time but #pragma once is very well supported across compilers but not actually part of the standard. The preprocessor may be a little faster with it as it is more simple to understand your exact intent.

#pragma once is less prone to making mistakes and it is less code to type.

To speed up compile time more just forward declare instead of including in .h files when you can.

I prefer to use #pragma once.

See this wikipedia article about the possibility of using both.


Share
Improve this answer
Follow
edited Jul 17 "09 at 15:34
answered Jul 17 "09 at 15:21
*

Brian R. BondyBrian R. Bondy
322k117117 gold badges583583 silver badges622622 bronze badges
19
| Show 14
more comments
186
I just wanted to add to this discussion that I am just compiling on VS and GCC, and used to use include guards. I have now switched to #pragma once, and the only reason for me is not performance or portability or standard as I don"t really care what is standard as long as VS and GCC support it, and that is that:

#pragma once reduces possibilities for bugs.

Xem thêm: Lời Bài Hát Chẳng Ai Là Của Riêng Ai Là Của Riêng Ai, Chang Ai La Cua Rieng Ai

It is all too easy to copy and paste a header file to another header file, modify it to suit ones needs, and forget to change the name of the include guard. Once both are included, it takes you a while to track down the error, as the error messages aren"t necessarily clear.


Share
Improve this answer
Follow
edited Nov 30 "14 at 9:57
answered Jul 22 "11 at 16:55
*

CookieCookie
11k1313 gold badges4747 silver badges7272 bronze badges
2
Add a comment |
154

#pragma once has unfixable bugs. It should never be used.

If your #include search path is sufficiently complicated, the compiler may be unable to tell the difference between two headers with the same basename (e.g. a/foo.h and b/foo.h), so a #pragma once in one of them will suppress both. It may also be unable to tell that two different relative includes (e.g. #include "foo.h" and #include "../a/foo.h" refer to the same file, so #pragma once will fail to suppress a redundant include when it should have.

This also affects the compiler"s ability to avoid rereading files with #ifndef guards, but that is just an optimization. With #ifndef guards, the compiler can safely read any file it isn"t sure it has seen already; if it"s wrong, it just has to do some extra work. As long as no two headers define the same guard macro, the code will compile as expected. And if two headers do define the same guard macro, the programmer can go in and change one of them.

Xem thêm: Tôi Tiễn Anh Lên Đường Trời Hôm Nay Mưa Nhiều Lắm, Tìm Bài Hát Với Lời (Kiếm Được 6 Bài)

#pragma once has no such safety net -- if the compiler is wrong about the identity of a header file, either way, the program will fail to compile. If you hit this bug, your only options are to stop using #pragma once, or to rename one of the headers. The names of headers are part of your API contract, so renaming is probably not an option.

(The short version of why this is unfixable is that neither the Unix nor the Windows filesystem API offer any mechanism that guarantees to tell you whether two absolute pathnames refer to the same file. If you are under the impression that inode numbers can be used for that, sorry, you"re wrong.)

(Historical note: The only reason I didn"t rip #pragma once and #import out of GCC when I had the authority to do so, ~12 years ago, was Apple"s system headers relying on them. In retrospect, that shouldn"t have stopped me.)

(Since this has now come up twice in the comment thread: The GCC developers did put quite a bit of effort into making #pragma once as reliable as possible; see GCC bug report 11569. However, the implementation in current versions of GCC can still fail under plausible conditions, such as build farms suffering from clock skew. I do not know what any other compiler"s implementation is like, but I would not expect anyone to have done better.)