Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. What is #ifndef QT_H for???
Forum Updated to NodeBB v4.3 + New Features

What is #ifndef QT_H for???

Scheduled Pinned Locked Moved General and Desktop
7 Posts 4 Posters 4.8k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bart_Vandewoestyne
    wrote on last edited by Bart_Vandewoestyne
    #1

    I am currently working my way into an older codebase, and in a lot of header files, I see things like this:

    #ifndef QT_H
    #include <QString>
    #include <QVector>
    #include <QDomDocument>
    #include <QMap>
    ... and other Qt includes ...
    #endif
    

    I am wondering why the #ifndef QT_H check is necessary. I tried googling for this, but could not find anything related to it. I did find this same construct in other code on the net, which makes me assume that it is or was a common thing to do. Is this something that used to be necessary for older code, but is deprecated nowadays? If anybody can provide me a link or book where this is explained, that would be very nice.

    Regards,
    Bart

    K 1 Reply Last reply
    0
    • B Bart_Vandewoestyne

      I am currently working my way into an older codebase, and in a lot of header files, I see things like this:

      #ifndef QT_H
      #include <QString>
      #include <QVector>
      #include <QDomDocument>
      #include <QMap>
      ... and other Qt includes ...
      #endif
      

      I am wondering why the #ifndef QT_H check is necessary. I tried googling for this, but could not find anything related to it. I did find this same construct in other code on the net, which makes me assume that it is or was a common thing to do. Is this something that used to be necessary for older code, but is deprecated nowadays? If anybody can provide me a link or book where this is explained, that would be very nice.

      Regards,
      Bart

      K Offline
      K Offline
      koahnig
      wrote on last edited by koahnig
      #2

      @Bart_Vandewoestyne
      That looks to me like a home-brewed method to reduce a bunch includes. IIRC it does not come from Qt.
      Most likely at the end of such a block QT_H is defined. If you include 10 different of your includes holding this, you make sure that the Qt headers are only included once instead of the reducndant 9 times in addition.

      Some people do it this way and put a lot of not required includes in their code and wonder why the compilation respectively the screening takes so long. This is than a counter measure.

      In my opinion it is better to think about the includes you really need.

      Vote the answer(s) that helped you to solve your issue(s)

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mcosta
        wrote on last edited by
        #3

        Hi and welcome to devnet,

        in C/C++ the synatx

        // my_header.h
        #ifndef XXXX
        #define XXXX
        
        ......
        
        #endif
        

        is called include guard; is a standard pattern to avoid multiple inclusion in the same source file.
        As @koahnig said QT_H is not defined in Qt but is something the developer self-made.

        NOTE: in modern C++ compilers you can achieve the same results using #pragma once

        // my_header.h
        # pragma once
        
        ....
        

        Once your problem is solved don't forget to:

        • Mark the thread as SOLVED using the Topic Tool menu
        • Vote up the answer(s) that helped you to solve the issue

        You can embed images using (http://imgur.com/) or (http://postimage.org/)

        1 Reply Last reply
        1
        • B Offline
          B Offline
          Bart_Vandewoestyne
          wrote on last edited by
          #4

          I think I've finally discovered the reason for these include guards. I think they are so-called "Redundant Include Guards" (sometimes also called "External Include Guards"), as discussed in Section 2.5 in "Large Scale C++ Software Design" by John Lakos. In that book on page 85, Lakos introduces the following 'Minor Design Rule':

          Place a redundant (external) include guard around each preprocessor include directive in every header file.

          For as far as I understand the book, this design rule exists mainly to reduce compilation times (preprocessor time actually...), but I would assume that nowadays, most development environments are smart enough to keep track of previously included headers files, which makes the design rule outdated.

          My educated guess is thus that removing these redundant include guards will not change anything to the program, it might only have an effect on the compilation (preprocessing) time.

          kshegunovK 1 Reply Last reply
          1
          • B Bart_Vandewoestyne

            I think I've finally discovered the reason for these include guards. I think they are so-called "Redundant Include Guards" (sometimes also called "External Include Guards"), as discussed in Section 2.5 in "Large Scale C++ Software Design" by John Lakos. In that book on page 85, Lakos introduces the following 'Minor Design Rule':

            Place a redundant (external) include guard around each preprocessor include directive in every header file.

            For as far as I understand the book, this design rule exists mainly to reduce compilation times (preprocessor time actually...), but I would assume that nowadays, most development environments are smart enough to keep track of previously included headers files, which makes the design rule outdated.

            My educated guess is thus that removing these redundant include guards will not change anything to the program, it might only have an effect on the compilation (preprocessing) time.

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #5

            @Bart_Vandewoestyne said in What is #ifndef QT_H for???:

            but I would assume that nowadays, most development environments are smart enough to keep track of previously included headers files, which makes the design rule outdated.

            Why would you assume that? The preprocessor cares not about redundancy if you don't force it to (either by adding a #pragma or an include guard). Something more, your code may be structured in such a way that redundant includes are needed, although this would be a bad design by itself. In any case the preprocessor is a pretty basic copy-paste machinery, it cares only for a handful of statements and about its simple syntax, not about the semantics.

            Read and abide by the Qt Code of Conduct

            B 1 Reply Last reply
            1
            • kshegunovK kshegunov

              @Bart_Vandewoestyne said in What is #ifndef QT_H for???:

              but I would assume that nowadays, most development environments are smart enough to keep track of previously included headers files, which makes the design rule outdated.

              Why would you assume that? The preprocessor cares not about redundancy if you don't force it to (either by adding a #pragma or an include guard). Something more, your code may be structured in such a way that redundant includes are needed, although this would be a bad design by itself. In any case the preprocessor is a pretty basic copy-paste machinery, it cares only for a handful of statements and about its simple syntax, not about the semantics.

              B Offline
              B Offline
              Bart_Vandewoestyne
              wrote on last edited by
              #6

              @kshegunov said in What is #ifndef QT_H for???:

              Why would you assume that?

              There are several reasons why I'm assuming that current compilers have the so-called include guard optimisation:

              1. In his book (first published in 1996), Lakos writes "Note that some development environments are smart enough to keep track of previously included header files, but many common environments are not." Being more than 20 years later now, my educated guess is that most development environments have caught up and are smart enough.

              2. There is a Stack Overflow post that indicates that redundant include guards are pointless for MSVC and GCC: http://stackoverflow.com/questions/1021357/wrapping-includes-in-ifndefs-adds-any-value

              3. The online gcc docs have a specific page where it is mentioned that CPP (being the C preprocessor) does not bother to rescan a file if it is already included: https://gcc.gnu.org/onlinedocs/cpp/Once-Only-Headers.html

              4. I've found an interesting blogpost about the topic and it even provides code to test your compiler for include guard optimization: http://bobarcher.org/software/include/index.html The results are here.

              The preprocessor cares not about redundancy if you don't force it to (either by adding a #pragma or an include guard). Something more, your code may be structured in such a way that redundant includes are needed, although this would be a bad design by itself. In any case the preprocessor is a pretty basic copy-paste machinery, it cares only for a handful of statements and about its simple syntax, not about the semantics.

              After having done some online research, I think I don't agree with the above. At least GCC's preprocessor does seem to have the so-called include guard optimization. Furthermore, redundant include guards are a technique introduced to speed up compilation (by avoiding the unnecessary re-opening of include files). I cannot imagine a situation where they would be needed for other reasons than for speeding up compilation. If you do not use them, the only consequence is that your compilation speed might go down.

              kshegunovK 1 Reply Last reply
              1
              • B Bart_Vandewoestyne

                @kshegunov said in What is #ifndef QT_H for???:

                Why would you assume that?

                There are several reasons why I'm assuming that current compilers have the so-called include guard optimisation:

                1. In his book (first published in 1996), Lakos writes "Note that some development environments are smart enough to keep track of previously included header files, but many common environments are not." Being more than 20 years later now, my educated guess is that most development environments have caught up and are smart enough.

                2. There is a Stack Overflow post that indicates that redundant include guards are pointless for MSVC and GCC: http://stackoverflow.com/questions/1021357/wrapping-includes-in-ifndefs-adds-any-value

                3. The online gcc docs have a specific page where it is mentioned that CPP (being the C preprocessor) does not bother to rescan a file if it is already included: https://gcc.gnu.org/onlinedocs/cpp/Once-Only-Headers.html

                4. I've found an interesting blogpost about the topic and it even provides code to test your compiler for include guard optimization: http://bobarcher.org/software/include/index.html The results are here.

                The preprocessor cares not about redundancy if you don't force it to (either by adding a #pragma or an include guard). Something more, your code may be structured in such a way that redundant includes are needed, although this would be a bad design by itself. In any case the preprocessor is a pretty basic copy-paste machinery, it cares only for a handful of statements and about its simple syntax, not about the semantics.

                After having done some online research, I think I don't agree with the above. At least GCC's preprocessor does seem to have the so-called include guard optimization. Furthermore, redundant include guards are a technique introduced to speed up compilation (by avoiding the unnecessary re-opening of include files). I cannot imagine a situation where they would be needed for other reasons than for speeding up compilation. If you do not use them, the only consequence is that your compilation speed might go down.

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by
                #7

                @Bart_Vandewoestyne said in What is #ifndef QT_H for???:

                At least GCC's preprocessor does seem to have the so-called include guard optimization.

                Yes, it seems it does. I wonder what would happen if you have stuff after the #endif though ...
                My point was rather that the preprocessor doesn't care about the contents in the ifdef block, so apparently GCC just optimizes out the file reading (i.e. finding the #endif and skipping the contents) as it already knows the header contains it. I still maintain that "keeping track of previously included headers files" is somewhat different from "include guard optimisation", as the latter implies a specific case - when there's include guard wrapping the whole of the header.

                I cannot imagine a situation where they would be needed for other reasons than for speeding up compilation.

                Me neither, so I don't use redundand guards.

                If you do not use them, the only consequence is that your compilation speed might go down.

                I'd go a step further and say that only your preprocessing time will be longer, the compiler runs after the preprocessor and has no notion of #ifdefs and the like. From its point of view nothing will have changed either way.

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved