   Comment Before Header Guards
  I've noticed I and others put a comment first on a header file, even before the include guards.Would this slow down compilation, or is "the compiler" or "the preprocessor" smart enough to see that it is just comments before the include guards?[Edited by - Boder on June 16, 2006 2:49:49 AM]
Quote:Original post by BoderI've noticed I and others put a comment first on a header file, even before the include guards.Would this slow down compilation, or is "the compiler" or "the preprocessor" smart enough to see that it is just comments before the include guards?As far as I know comments are (with some exceptions? like on preprocessor lines maybe it's not seen as a comment) flat out ignored, probably removed before the compiler even sees the code.  I wouldn't think it would slow down compilation by more than a millisecond, if it had to be removed more than once and it was included hundreds of times.But...I'm guessing!   ;  Yeah I'm going to guess that the comments won't mess up the "Include Guard Detection Algorithm"Thanks for the advice [grin][Edited by - Boder on June 16, 2006 2:15:53 AM];  The compiler and preprocessor have to be smart enough to understand comments, otherwise they wouldn't work.The file has to be opened and processed anyway to get to the include guards, and the (trivial) recognition of comments is nothing in the scheme of what a compiler has to do. Consider that even if you have your #ifndef INCLUDE_GUARD as the first line of the file, the whole file needs to be processed to get to the #endif...   ;  I'm okay with it getting opened and parsed once, but I want to make sure it gets the special flag saying "this header has include guards" so it isn't opened/parsed again until the next .cpp file.   ;  It seems that you are misunderstanding something. There is no such thing as an header guard detection algorithm. The preprocessor interprets the preprocessor directives in a way that prevent redefition of symbols: #ifndef SOME_SYMBOL#define SOME_SYMBOLclass A { ... };#endif // SOME_SYMBOLSimply means that is SOME_SYMBOL is defined , the part between #ifndef and #endif is not copied into the compilation unit. If SOME_SYMBOL is not defined, we make sure that it will be defined - to prevent another possible inclusion of the file. That's all. No special algorithm, just a flat out interpretation of what's written.This is the same for comments. Everything that is between /* and */ is ignored, and everything after // is ignored until the end of the line. That's all. There is nothing complex in a C/C++ preprocessor :)Regards,   ;  Emmanuel Deloget, thank you for the explanation. You made me stop and think about what is actually going on.There was a thread mentioning #pragma once and how it might allow faster compilation compared to traditional include guards. But it was also mentioned that recent compilers like GCC and Visual Studio could detect include guards just like #pragma once to prevent needless re-reading and re-parsing of the file. I want to make sure that if something like this happens#include <header.h>#include <header.h>The preprocessor won't bother at all with the second #include, but of course it would have to if the header wasn't completely wrapped in header guards. Of course it also has to be careful of #undef but I'm sure it looks for that.   ;Quote:There was a thread mentioning #pragma once and how it might allow faster compilation compared to traditional include guards. But it was also mentioned that recent compilers like GCC and Visual Studio could detect include guards just like #pragma once to prevent needless re-reading and re-parsing of the file. I want to make sure that if something like this happensI'd assume any header guard detection optimization would be smart enough to ignore comments. I also wouldn't worry to much about this - your compiler will probably spend an insignificant amount of time in the preprocessor compared to the rest of the compilation.   ;Quote:#include <header.h>#include <header.h>The preprocessor won't bother at all with the second #include, but of course it would have to if the header wasn't completely wrapped in header guards. Of course it also has to be careful of #undef but I'm sure it looks for that.It will open and process both files. It has to. An explanation:// header.h#ifndef HEADER_H_#define HEADER_H_class Foo { /* details */ };#endif // HEADER_H_// somefile.cpp#include "header.h"  // "" versus <> irrelevant to discussion, btw#include "header.h"int main(void) { /* details */ }After preprocessing of somefile.cpp, it will look like this (I have assumed the preprocessor will not remove comments, to provide some clarification):// somefile.cpp// header.h#ifndef HEADER_H_class Foo { /* details */ }; // HEADER_H_// header.h // HEADER_H_int main(void) { /* details */ }Note how the #ifndef / #define / #endif bits were not copied to the preprocessed translation unit (as Emmanuel Deloget said). header.h was opened and processed twice, but its content was only pasted once because of how we used the preprocessor.This is the typical use of header files, and the way you'd typically expect them to behave. Unfortunately there is no mandate that headers / preprocessor includes must be used this way, and so the preprocessor should not be written to assume that once a file is preprocessed (#include'd) for a given translation unit (ex., somefile.cpp), it will be ignored (not opened or processed at all) if it was #include'd again from within that original translation unit.For example, there are techniques for generating enumeration values and such by recursively or multiply-including a header file (with different sets of #define's) that would break if the preprocessor ignored repeated inclusions implicitly. While those sorts of techniques are amazingly ugly and hard to follow, they are not technically exploiting a bug, flaw, or standardization loophole in the preprocessor's behavior. That's why many development suites offer some kind of #pragma once option that can be used to mark the file as ignorable if multiply-included.   ;  I'm saying, given that a header file is wrapped in traditional include guards, why can't the preprocessor safely ignore any subsequent attempts to #include the header?It can, because as long as the symbol (HEADER_H_) remains defined, absolutely nothing is copied into the translation unit, effectively making it a noop.If I was a compiler writer, I would realize people use include guards and check whether a particular header uses them. If it does, I would map the header's filename to the particular symbol it uses and whether it is currently defined. After the first #include, the header would be added to the map and the symbold would be defined.If I find #undef HEADER_H_ then I ... I guess I would have to maintain a reverse map of symbols to header files. I would turn off the symbol and #include the header again wherever I see the directive.   