Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. #define not const?

#define not const?

Scheduled Pinned Locked Moved C / C++ / MFC
question
7 Posts 4 Posters 0 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.
  • W Offline
    W Offline
    Waldermort
    wrote on last edited by
    #1

    To make my code more readable I'm trying to use a set of defined values in a switch statement. Basically I have a 4 CHAR tag I want to convert to a DWORD.

    //#define _makeTag(a,b,c,d) ((#@a << 24) | (#@b << 16) | (#@c << 8) | #@d)
    //#define tag_cmap _makeTag(c,m,a,p)
    #define _makeTag(x) ((#x[0] << 24) | (#x[1] << 16) | (#x[2] << 8) | #x[3])
    #define tag_cmap _makeTag(cmap)

    In the above I have a 4 CHAR string "cmap" which in DWORD form should be 0x636d6170. However when using in a switch statement the compiler complains that it's not constant. The commented line works, however I believe it to be unreadable. Any suggestions? My previous method was to use a union but that required a loop over all the values, hence slow code.

    Waldermort

    T _ S 3 Replies Last reply
    0
    • W Waldermort

      To make my code more readable I'm trying to use a set of defined values in a switch statement. Basically I have a 4 CHAR tag I want to convert to a DWORD.

      //#define _makeTag(a,b,c,d) ((#@a << 24) | (#@b << 16) | (#@c << 8) | #@d)
      //#define tag_cmap _makeTag(c,m,a,p)
      #define _makeTag(x) ((#x[0] << 24) | (#x[1] << 16) | (#x[2] << 8) | #x[3])
      #define tag_cmap _makeTag(cmap)

      In the above I have a 4 CHAR string "cmap" which in DWORD form should be 0x636d6170. However when using in a switch statement the compiler complains that it's not constant. The commented line works, however I believe it to be unreadable. Any suggestions? My previous method was to use a union but that required a loop over all the values, hence slow code.

      Waldermort

      T Offline
      T Offline
      TheGreatAndPowerfulOz
      wrote on last edited by
      #2

      no, it's not const. Because it's not a compile-time operation. You're accessing a memory location. If you were to look at the generated C-code, it would look like the following:

      (("cmap"[0] << 24) | ("cmap"[1] << 16) | ("cmap"[2] << 8) | ("cmap"[3]))

      So, it's runtime code, *not* a constant. You could try assigning it to a constant though, as follows:

      const tag_cmap = _makeTag(cmap);

      instead of the

      #define tag_cmap

      If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams
      You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun

      W 1 Reply Last reply
      0
      • T TheGreatAndPowerfulOz

        no, it's not const. Because it's not a compile-time operation. You're accessing a memory location. If you were to look at the generated C-code, it would look like the following:

        (("cmap"[0] << 24) | ("cmap"[1] << 16) | ("cmap"[2] << 8) | ("cmap"[3]))

        So, it's runtime code, *not* a constant. You could try assigning it to a constant though, as follows:

        const tag_cmap = _makeTag(cmap);

        instead of the

        #define tag_cmap

        If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams
        You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun

        W Offline
        W Offline
        Waldermort
        wrote on last edited by
        #3

        ahmed zahmed wrote:

        You're accessing a memory location.

        LOL, That thought hit me right after posting the message. Compiler still complains when assigning to a const. I've decided to go with my first method but instead to use _makeTag('c','m','a','p') directly in the switch. Thanks again.

        Waldermort

        1 Reply Last reply
        0
        • W Waldermort

          To make my code more readable I'm trying to use a set of defined values in a switch statement. Basically I have a 4 CHAR tag I want to convert to a DWORD.

          //#define _makeTag(a,b,c,d) ((#@a << 24) | (#@b << 16) | (#@c << 8) | #@d)
          //#define tag_cmap _makeTag(c,m,a,p)
          #define _makeTag(x) ((#x[0] << 24) | (#x[1] << 16) | (#x[2] << 8) | #x[3])
          #define tag_cmap _makeTag(cmap)

          In the above I have a 4 CHAR string "cmap" which in DWORD form should be 0x636d6170. However when using in a switch statement the compiler complains that it's not constant. The commented line works, however I believe it to be unreadable. Any suggestions? My previous method was to use a union but that required a loop over all the values, hence slow code.

          Waldermort

          _ Offline
          _ Offline
          _Superman_
          wrote on last edited by
          #4

          It turns out that you do not need a macro at all to do what you want. Try this -

          DWORD d = 'cmap';

          Please note the single quotation marks.

          «_Superman_»  _I love work. It gives me something to do between weekends.

          _Microsoft MVP (Visual C++)

          Polymorphism in C

          W 1 Reply Last reply
          0
          • _ _Superman_

            It turns out that you do not need a macro at all to do what you want. Try this -

            DWORD d = 'cmap';

            Please note the single quotation marks.

            «_Superman_»  _I love work. It gives me something to do between weekends.

            _Microsoft MVP (Visual C++)

            Polymorphism in C

            W Offline
            W Offline
            Waldermort
            wrote on last edited by
            #5

            Nice! Out of curiosity what compiler are you using? I think I may have tried that back on VS8 but with errors.

            Waldermort

            _ 1 Reply Last reply
            0
            • W Waldermort

              Nice! Out of curiosity what compiler are you using? I think I may have tried that back on VS8 but with errors.

              Waldermort

              _ Offline
              _ Offline
              _Superman_
              wrote on last edited by
              #6

              I currently use VS2010, but I'm sure this works in older compilers, because this type of assignment is used to tag memory allocations in kernel mode code from ages ago.

              «_Superman_»  _I love work. It gives me something to do between weekends.

              _Microsoft MVP (Visual C++)

              Polymorphism in C

              1 Reply Last reply
              0
              • W Waldermort

                To make my code more readable I'm trying to use a set of defined values in a switch statement. Basically I have a 4 CHAR tag I want to convert to a DWORD.

                //#define _makeTag(a,b,c,d) ((#@a << 24) | (#@b << 16) | (#@c << 8) | #@d)
                //#define tag_cmap _makeTag(c,m,a,p)
                #define _makeTag(x) ((#x[0] << 24) | (#x[1] << 16) | (#x[2] << 8) | #x[3])
                #define tag_cmap _makeTag(cmap)

                In the above I have a 4 CHAR string "cmap" which in DWORD form should be 0x636d6170. However when using in a switch statement the compiler complains that it's not constant. The commented line works, however I believe it to be unreadable. Any suggestions? My previous method was to use a union but that required a loop over all the values, hence slow code.

                Waldermort

                S Offline
                S Offline
                Stefan_Lang
                wrote on last edited by
                #7

                WalderMort wrote:

                Any suggestions?

                Why, yes: don't use macros, they make your code unreadable ;p No, seriously: using macros is dangerous, with very few exceptions. Regarding your example, your choice of symbol alone already breaks two common safeguards against macro problems: 1. Do not ever use a symbol with starting '_'! This is what the system libraries use internaly to prevent name clashes with any symbols the programmer may define! The problem with name clashes and macros is that macros clash silently, and may break system libraries, resulting in very hard to trace runtime errors (or compiler error,s, if you're lucky) 2. Use capital letters for symbols denoting const or #define symbols. This, also, has to do with preventing name clashes. It may seem overkill, but better be safe than sorry. I've spent many, many weeks hunting down errors caused my macro name clashes caused by other people's code (and in some cases even by MS #defines!). Do yourself (and everyone else) a favor and don't add to that misery!

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups