4

I am studying boost libraries, and something strange to me is many libraries use this kind of code:

#ifndef BOOST_SERIALIZATION_ACCESS_HPP
#define BOOST_SERIALIZATION_ACCESS_HPP

// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif

MSDN explicitly states that:

There is no advantage to use of both the #include guard idiom and #pragma once in the same file

I can't understand what might the reason be. include guard does the job anyway so why we bother to write pragma once too?

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
shayan
  • 361
  • 3
  • 14
  • 1
    Obviously, whoever wrote that code didn't read MSDN's documentation. – Remy Lebeau Apr 29 '18 at 19:19
  • @RemyLebeau I see that a lot, and we are talking about boost! It would be very strange if it is such obvious and no one has detected it yet. – shayan Apr 29 '18 at 19:33
  • 2
    MSDN did not state that 15 years ago. Boost tries to support some ancient compilers that might not work the way we expect them to. – Bo Persson Apr 29 '18 at 20:01

1 Answers1

8

Actually there might be a small difference inside the compiler. When compiler encounters #pragma once then it can internally mark that this file is included. When it encounters #include for this file for the second time it won't bother even to open it, it will just ignore the #include statement.

With only include guard the preprocessor has to parse the whole file every time it's included to find a matching #endif. Theoretically, if really complicated and large include files are included multiple times this can affect compilation time.

Other than that, include guard and #pragma once behave the same way. Both of them are usually used because #pragma once is not guaranteed to be supported on all compilers.

Edit:

Compiler might have the ability to detect that include guard's statements are surrounding the whole file's code and deduce that it's an include guard, producing exactly the same behavior as with #pragma once. If that's the case then MSDN's claim is correct.

BJovke
  • 1,737
  • 15
  • 18
  • So after the compiler encounters a #pragma once, it will cancel its operation for finding a matching #endif and just ignore the file, am I right? – shayan Apr 29 '18 at 19:48
  • 1
    First time it encounters it it will process the whole file, of course. But the second time it encounters the `#include` for this file it will just ignore the `#include`. I've added an edit where there's a possibility that compiler detects the include guard also and it behaves the same way in both cases. But we can't know the internals of the MS compiler... – BJovke Apr 29 '18 at 19:53
  • 1
    MSDN's claim is correct *now*. It might have been different in 2002 when boost.serialization was introduced. – Bo Persson Apr 29 '18 at 20:06