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. Best way to handle large number of preprocessor definitions?
Forum Updated to NodeBB v4.3 + New Features

Best way to handle large number of preprocessor definitions?

Scheduled Pinned Locked Moved General and Desktop
9 Posts 3 Posters 4.2k Views 1 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.
  • F Offline
    F Offline
    floatingWoods
    wrote on last edited by
    #1

    Hello,

    I used to use a precompiled header for that. Is there another method?
    Putting "DEFINES" in the project file seems problematic for various reasons.

    What is the "right" way to do it?

    1 Reply Last reply
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      What do you need to do with those definitions?

      You can try const variables. These are like "#define"s, but you also get compiler type-checking.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      0
      • F Offline
        F Offline
        floatingWoods
        wrote on last edited by
        #3

        Thank you for your reply!

        Actually that's where I decide what part of code are being compiled.
        One thing I forgot to mention: the application is a Qt application, but can also be compiled with MSVS for compatibility reasons. So I need to support Qt and MSVS compilation schemes.
        Typically, I have things similar to that (following is only a small extract):

        [code]
        #ifdef RELEASE_EVALUATION
        #define CHECK_LICENSE
        #define CHECK_WEEKLYPING
        #define COMPILATION_VERSION COMPILATION_VERSION_EVALUATION
        #define OUTPUT_FILENAME "myApp.dll"
        #define LIB3D_IMPORTER_REQUIRED
        #define SHOW_EVALUATION_VERSION_TAG
        #define DEFAULT_OPTIONS (ALLOW_IMPORT_EXPORT|ALLOW_SCRIPT_EDITION|ALLOW_EDIT_MODES)
        #endif

        #ifdef RELEASE_FULL
        #define CHECK_LICENSE
        #define CHECK_WEEKLYPING
        #define COMPILATION_VERSION COMPILATION_VERSION_PAYING
        #define OUTPUT_FILENAME "myApp.dll"
        #define DONT_START_IF_NO_VALID_LICENSE_FOUND
        #define LIB3D_IMPORTER_REQUIRED
        #define DEFAULT_OPTIONS (0)
        #endif

        #define ROTATE_LEFT_16(data,amount) (WORD(WORD(WORD(data) << (amount&0x0f)) | (WORD(data) >> (16-(amount&0x0f))))
        #define XXX_MIN(a,b) (((a)<(b)) ? (a) : (b))
        #define XXX_MAX(a,b) (((a)>(b)) ? (a) : (b))
        #define IS_BIT_SET(var,bit) (((var) & (1<<(bit)))!=0)
        #define SET_BIT(var,bit) ((var) |= (1<<(bit)))
        #define CLEAR_BIT(var,bit) ((var) &= (~(1<<(bit))))
        #define TOGGLE_BIT(var,bit) ((var) ^= (1<<(bit)))
        #define SET_CLEAR_BIT(var,bit,on) ((on) ? SET_BIT((var),(bit)) : CLEAR_BIT((var),(bit)) )
        #define RAND_FLOAT (rand()/(float)RAND_MAX)
        #define stdVector std::vector
        #define SERVER_PACKET_SIZE 620
        #define FLOATING_SERVER_PACKET_SIZE 320
        [/code]

        1 Reply Last reply
        0
        • JKSHJ Offline
          JKSHJ Offline
          JKSH
          Moderators
          wrote on last edited by
          #4

          [quote author="floatingWoods" date="1353157652"]Thank you for your reply!

          Actually that's where I decide what part of code are being compiled.

          ...

          [code]
          #ifdef RELEASE_EVALUATION
          #define CHECK_LICENSE
          #define CHECK_WEEKLYPING
          #define COMPILATION_VERSION COMPILATION_VERSION_EVALUATION
          #define OUTPUT_FILENAME "myApp.dll"
          #define LIB3D_IMPORTER_REQUIRED
          #define SHOW_EVALUATION_VERSION_TAG
          #define DEFAULT_OPTIONS (ALLOW_IMPORT_EXPORT|ALLOW_SCRIPT_EDITION|ALLOW_EDIT_MODES)
          #endif

          #ifdef RELEASE_FULL
          #define CHECK_LICENSE
          #define CHECK_WEEKLYPING
          #define COMPILATION_VERSION COMPILATION_VERSION_PAYING
          #define OUTPUT_FILENAME "myApp.dll"
          #define DONT_START_IF_NO_VALID_LICENSE_FOUND
          #define LIB3D_IMPORTER_REQUIRED
          #define DEFAULT_OPTIONS (0)
          #endif
          [/code]
          [/quote]
          You're welcome :)

          If you want to choose which part of the code to compile, #define and #ifdef is probably the easiest way... but it will make your code messier.

          [quote]One thing I forgot to mention: the application is a Qt application, but can also be compiled with MSVS for compatibility reasons. So I need to support Qt and MSVS compilation schemes.[/quote]Sorry, I'm not sure what you mean here. Do you mean compile using Qt Creator, as well as MSVS? You can use MSVS to compile Qt applications.

          [quote]
          [code]
          #define ROTATE_LEFT_16(data,amount) (WORD(WORD(WORD(data) << (amount&0x0f)) | (WORD(data) >> (16-(amount&0x0f))))
          #define XXX_MIN(a,b) (((a)<(b)) ? (a) : (b))
          #define XXX_MAX(a,b) (((a)>(b)) ? (a) : (b))
          #define IS_BIT_SET(var,bit) (((var) & (1<<(bit)))!=0)
          #define SET_BIT(var,bit) ((var) |= (1<<(bit)))
          #define CLEAR_BIT(var,bit) ((var) &= (~(1<<(bit))))
          #define TOGGLE_BIT(var,bit) ((var) ^= (1<<(bit)))
          #define SET_CLEAR_BIT(var,bit,on) ((on) ? SET_BIT((var),(bit)) : CLEAR_BIT((var),(bit)) )
          #define RAND_FLOAT (rand()/(float)RAND_MAX)
          #define stdVector std::vector
          #define SERVER_PACKET_SIZE 620
          #define FLOATING_SERVER_PACKET_SIZE 320
          [/code]
          [/quote]
          People used to manipulate bits to save memory. But, modern computers have lots of memory, so there is not much benefit to manipulating bits directly any more. I would recommend using normal variables/enums instead of bit-manipulation preprocessor macros. It makes code easier to maintain, and you can remove lots of "#define"s.

          Also, instead of
          @
          #define stdVector std::vector
          @
          it's better to use
          @
          typedef std::vector stdVector;
          @

          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

          1 Reply Last reply
          0
          • F Offline
            F Offline
            floatingWoods
            wrote on last edited by
            #5

            Thanks again JKSH!

            Sorry for the confusion. Actually the original application was a visual studio project and pure MFC. That application can still be compiled within visual studio (i.e. all Qt code is excluded in that case with many ifdef-s).

            When compiling with Qt Creator, then all the MFC code gets excluded (here too, with lots of ifdef-s).

            That's actually the main reason why I have so many "defines" in my precompiled header!

            1 Reply Last reply
            0
            • M Offline
              M Offline
              MuldeR
              wrote on last edited by
              #6

              If you have a lot of "global" defines, a common approach is to put them all into a file "config.h" (or however you prefer to call it) and include that header file from all other files where you might need those defines.

              For example, you could put the following code into your "config.h" file:

              @ #ifdef RELEASE_EVALUATION
              #define CHECK_LICENSE
              #define CHECK_WEEKLYPING
              #define COMPILATION_VERSION COMPILATION_VERSION_EVALUATION
              #define OUTPUT_FILENAME "myApp.dll"
              #define LIB3D_IMPORTER_REQUIRED
              #define SHOW_EVALUATION_VERSION_TAG
              #define DEFAULT_OPTIONS (ALLOW_IMPORT_EXPORT|ALLOW_SCRIPT_EDITION|ALLOW_EDIT_MODES)
              #endif

              #ifdef RELEASE_FULL
                #define CHECK_LICENSE
                #define CHECK_WEEKLYPING
                #define COMPILATION_VERSION COMPILATION_VERSION_PAYING
                #define OUTPUT_FILENAME "myApp.dll"
                #define DONT_START_IF_NO_VALID_LICENSE_FOUND
                #define LIB3D_IMPORTER_REQUIRED
                #define DEFAULT_OPTIONS (0)
              #endif
              
              [...]@
              

              And then, in your project file, you only add either "-DRELEASE_EVALUATION" or "-DRELEASE_FULL" to the compiler flags, depending on what configuration of the app your are going to build this time.

              BTW: You make it sound like building the app with "Qt" (you probably mean qmake + mingw here?!) and "Visual Studio" (msvc) are two mutually exclusive things. But Qt-based applications can be built with Visual Studio just fine, so you might be able to drop MFC altogether. Making the switch from MFC to Qt is such a big relief! :-)

              My OpenSource software at: http://muldersoft.com/

              Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

              Go visit the coop: http://youtu.be/Jay...

              1 Reply Last reply
              0
              • F Offline
                F Offline
                floatingWoods
                wrote on last edited by
                #7

                Thanks MuldeR!

                The idea to put all defines into a config file is fine, but what if I forget to include that config file in another file? Then it might just compile file, but with the wrong defines. For example, if my config file has following content:

                [code]
                #define INCLUDE_SPECIAL_FUNCTIONALITY
                [/code]

                and my other file has something like:

                [code]
                #ifdef INCLUDE_SPECIAL_FUNCTIONALITY

                do something

                #else

                do something else

                #endif
                [/code]

                If I forget to include the config file, it will compile fine, with the "do something else" code. But that should rather be the "do something" code.

                That is a bug difficult to catch. With a precompiled header, you know that it is used for all other files.

                Then, I know that I can compile a Qt project with MSVC, and I am also doing it. I just need to keep the MFC version too to support old versions of the application. I will completely drop the MFC code in 1-2 years

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  MuldeR
                  wrote on last edited by
                  #8

                  Well, to prevent that case, you could actually assign a value to those preprocessor definitions:

                  @ #ifdef RELEASE_EVALUATION
                  #define INCLUDE_SPECIAL_FUNCTIONALITY 1
                  #endif

                  #ifdef RELEASE_FULL
                  #define INCLUDE_SPECIAL_FUNCTIONALITY 0
                  #endif@

                  And then:

                  @#if defined(INCLUDE_SPECIAL_FUNCTIONALITY) && (INCLUDE_SPECIAL_FUNCTIONALITY == 1)

                  /* do something */

                  #elif defined(INCLUDE_SPECIAL_FUNCTIONALITY) && (INCLUDE_SPECIAL_FUNCTIONALITY == 0)

                  /* do something */

                  #else

                  #error Configuration error. Forgot to include config.h ???

                  #endif@

                  Also you might want to do something like this in your config.h:

                  @#if defined(RELEASE_EVALUATION)

                  /* defines for evolution here*/

                  #elif defined(RELEASE_FULL)

                  /* defines for full version here*/

                  #else

                  #error Neither RELEASE_EVALUATION nor RELEASE_FULL is defined!

                  #endif@

                  [EDIT]

                  You may also do this, at least in Visual Studio:
                  http://msdn.microsoft.com/en-us/library/8c5ztk84(v=vs.100).aspx

                  bq. /FI (Name Forced Include File)
                  This option has the same effect as specifying the file with double quotation marks in an #include directive on the first line of every source file

                  You can do the same with MinGW/GCC by adding "-include config.h" to your CFLAGS/CXXFLAGS, I think.

                  My OpenSource software at: http://muldersoft.com/

                  Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

                  Go visit the coop: http://youtu.be/Jay...

                  1 Reply Last reply
                  0
                  • JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on last edited by
                    #9

                    [quote author="floatingWoods" date="1353165219"]Actually the original application was a visual studio project and pure MFC. That application can still be compiled within visual studio (i.e. all Qt code is excluded in that case with many ifdef-s).

                    When compiling with Qt Creator, then all the MFC code gets excluded (here too, with lots of ifdef-s).[/quote]

                    You don't have to do that. Like MuldeR said, you can use Visual Studio to compile Qt programs.

                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                    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