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

I"m working on a codebase that is known to lớn only run on windows & 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 & is less error prone when copying and pasting. It is also slightly less ugly ;)

Note: lớn get the faster compile times we could use Redundant Include Guards but that adds a tight coupling between the included tệp tin and the including file. Usually it"s ok because the guard should be based on the file name và would only change if you needed to lớn 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
Improve sầu this question
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
Add a phản hồi |

13 Answers 13

Active Oldest Votes
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 khổng lồ underst& your exact intent.

#pragma once is less prone to lớn making mistakes & it is less code lớn type.

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

I prefer to lớn use #pragma once.

See this wikipedia article about the possibility of using both.

Improve sầu this answer
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
| Show 14
more comments
I just wanted lớn add to this discussion that I am just compiling on VS and GCC, and used to use include guards. I have now switched khổng lồ #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 và GCC support it, & 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 & paste a header file lớn another header file, modify it khổng lồ suit ones needs, and forget khổng lồ change the name of the include guard. Once both are included, it takes you a while khổng lồ track down the error, as the error messages aren"t necessarily clear.

Improve sầu this answer
edited Nov 30 "14 at 9:57
answered Jul 22 "11 at 16:55

11k1313 gold badges4747 silver badges7272 bronze badges
Add a phản hồi |

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

If your #include tìm kiếm 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 và b/foo.h), so a #pragma once in one of them will suppress both. It may also be unable lớn tell that two different relative sầu includes (e.g. #include "foo.h" & #include "../a/foo.h" refer to the same file, so #pragma once will fail khổng lồ suppress a redundant include when it should have.

This also affects the compiler"s ability khổng lồ avoid rereading files with #ifndef guards, but that is just an optimization. With #ifndef guards, the compiler can safely read any tệp tin it isn"t sure it has seen already; if it"s wrong, it just has lớn 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 tệp tin, either way, the program will fail lớn compile. If you hit this bug, your only options are khổng lồ stop using #pragma once, or to lớn 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 lớn the same tệp tin. 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 và #import out of GCC when I had the authority khổng lồ vị 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 inkhổng lồ 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 clochồng skew. I vày not know what any other compiler"s implementation is like, but I would not expect anyone to lớn have done better.)