#pragma once
obviously refers to the file as a whole
The use of #pragma once can reduce build times, as the compiler won't
open and read the file again after the first #include of the file in
the translation unit.
really - if not to file - for what it can be related ?
the conditional compilation , so called guard idiom related not to file but to block of code. really - where, how stated that some condition related to file ?!
it related to block beginning with #if*
and ended with #endif
. compiler anyway need include this file again.
let do some tests. also here will be very useful cl(msvc) compiler option /showIncludes
let create header.h
// header.h
#ifndef HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
and then
#include "header.h"
#include "header.h"
only once in log
1>Note: including file: .\header.h
so header.h really included only once here.
but if do this
// header.h
#if !defined HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
or this
#if !defined(HEADER_H_)
#define HEADER_H_
int g_a = 0;
#endif
and
#include "header.h"
#include "header.h"
already 2 lines in log - header.h included 2 time.
1>Note: including file: .\header.h
1>Note: including file: .\header.h
so #ifndef HEADER_H_
have different effect compare #if !defined(HEADER_H_)
or if do
// header.h
#ifndef HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
#define XYZ
or
// header.h
#if __LINE__ // any not empty statement
#endif
#ifndef HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
and
#include "header.h"
#include "header.h"
already
1>Note: including file: .\header.h
1>Note: including file: .\header.h
again 2 lines in log - header.h included 2 time.
so if exist any not empty ( comments, sequences of whitespace characters (space, tab, new-line)) statement outside first conditional block - file already included more times.
of course possible and do next
// header.h
#include "header.h"
#undef HEADER_H_
#include "header.h"
in this case
1>Note: including file: .\header.h
1>Note: including file: .\header.h
1>.\header.h(4): error C2374: 'g_a': redefinition; multiple initialization
1>.\header.h(4): note: see declaration of g_a'
and of course in case
// header.h
#pragma once
int g_b = 0;
and
#include "header.h"
#include "header.h"
only single line
1>Note: including file: .\header.h
so based on tests can make next conclusion - if cl(msvc) - view that file have pattern
#ifndef macro // but not #if !defined macro
#define macro
// all code only here
#endif
macro associates with the file and then as long as it is not undefined - the file will not be included more. this is implicit optimization by specific compiler. and very fragile. any not white space or comment statement break it. even despite documented that #ifndef HEADER_H_
quivalently to #if !defined HEADER_H_
- by fact this is not true.