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. Other Discussions
  3. The Weird and The Wonderful
  4. My introduction to "##"

My introduction to "##"

Scheduled Pinned Locked Moved The Weird and The Wonderful
careerhardwarequestion
24 Posts 10 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.
  • T Offline
    T Offline
    Todd_s02
    wrote on last edited by
    #1

    I was never one for the intricacies of the C preprocessor. On my latest project, apparently (or rather, unfortunately) someone is. An .h file has a bunch of definitions (real variable names changed to protect the innocent): statedefs.h: makeState(State1, 0x01) makeState(State2, 0x02) makeState(State3, 0x03) Odd, I think, but ok. Then I go look up "makeState". What the... 3 entries? That's not a good sign. Instance 1: #define makeState(NAME, NUM) ST_##NAME## = ##NUM##, typedef enum { #include "statedefs.h" ST_LAST } statetype; Instance 2: Embedded in the middle of a function(!) #undef makestate #define makeState(NAME, NUM) somevariable++; #include "statedefs.h" Instance 3: #define makestate(NAME, NUM) { "ST_"#NAME,0,0}, sometype stateinfo[] = { #include "statedefs.h" } There are no external programs being used, no weird autogeneration stuff.. the entire set of code is a replacement for: enum { ST_State1 = 1, ST_State2 = 2, ST_State3 = 3, ST_LAST } Most editors I've tried cannot tag it, due to the preprocessor concatenation used ("##" in instance 1). References don't work either. And this is one of the easier to read examples of preprocessor abuse... I just try and remind myself that code written this way makes it that much easier on my next job interview!

    M P P K 4 Replies Last reply
    0
    • T Todd_s02

      I was never one for the intricacies of the C preprocessor. On my latest project, apparently (or rather, unfortunately) someone is. An .h file has a bunch of definitions (real variable names changed to protect the innocent): statedefs.h: makeState(State1, 0x01) makeState(State2, 0x02) makeState(State3, 0x03) Odd, I think, but ok. Then I go look up "makeState". What the... 3 entries? That's not a good sign. Instance 1: #define makeState(NAME, NUM) ST_##NAME## = ##NUM##, typedef enum { #include "statedefs.h" ST_LAST } statetype; Instance 2: Embedded in the middle of a function(!) #undef makestate #define makeState(NAME, NUM) somevariable++; #include "statedefs.h" Instance 3: #define makestate(NAME, NUM) { "ST_"#NAME,0,0}, sometype stateinfo[] = { #include "statedefs.h" } There are no external programs being used, no weird autogeneration stuff.. the entire set of code is a replacement for: enum { ST_State1 = 1, ST_State2 = 2, ST_State3 = 3, ST_LAST } Most editors I've tried cannot tag it, due to the preprocessor concatenation used ("##" in instance 1). References don't work either. And this is one of the easier to read examples of preprocessor abuse... I just try and remind myself that code written this way makes it that much easier on my next job interview!

      M Offline
      M Offline
      Michael Dunn
      wrote on last edited by
      #2

      #define makeState(NAME, NUM) ST_##NAME## = ##NUM##,

      :wtf: To add insult to, well, insult - he only needed the first ##. Maybe he thought the macro params needed to be "quoted" with ## ?

      --Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ Ford, what's this fish doing in my ear?

      1 Reply Last reply
      0
      • T Todd_s02

        I was never one for the intricacies of the C preprocessor. On my latest project, apparently (or rather, unfortunately) someone is. An .h file has a bunch of definitions (real variable names changed to protect the innocent): statedefs.h: makeState(State1, 0x01) makeState(State2, 0x02) makeState(State3, 0x03) Odd, I think, but ok. Then I go look up "makeState". What the... 3 entries? That's not a good sign. Instance 1: #define makeState(NAME, NUM) ST_##NAME## = ##NUM##, typedef enum { #include "statedefs.h" ST_LAST } statetype; Instance 2: Embedded in the middle of a function(!) #undef makestate #define makeState(NAME, NUM) somevariable++; #include "statedefs.h" Instance 3: #define makestate(NAME, NUM) { "ST_"#NAME,0,0}, sometype stateinfo[] = { #include "statedefs.h" } There are no external programs being used, no weird autogeneration stuff.. the entire set of code is a replacement for: enum { ST_State1 = 1, ST_State2 = 2, ST_State3 = 3, ST_LAST } Most editors I've tried cannot tag it, due to the preprocessor concatenation used ("##" in instance 1). References don't work either. And this is one of the easier to read examples of preprocessor abuse... I just try and remind myself that code written this way makes it that much easier on my next job interview!

        P Offline
        P Offline
        Pete OHanlon
        wrote on last edited by
        #3

        That's somebody trying to be clever just to show off. I'm a great believer in the KISS principle, and this person deserves to be severely slapped with a wet haddock.

        Deja View - the feeling that you've seen this post before.

        M 1 Reply Last reply
        0
        • P Pete OHanlon

          That's somebody trying to be clever just to show off. I'm a great believer in the KISS principle, and this person deserves to be severely slapped with a wet haddock.

          Deja View - the feeling that you've seen this post before.

          M Offline
          M Offline
          Marcus J Smith
          wrote on last edited by
          #4

          Pete O`Hanlon wrote:

          KISS

          Yeah I wish people would remember that...dangit!


          CleaKO

          "I think you'll be okay here, they have a thin candy shell. 'Surprised you didn't know that.'" - Tommy (Tommy Boy)
          "Fill it up again! Fill it up again! Once it hits your lips, it's so good!" - Frank the Tank (Old School)

          T 1 Reply Last reply
          0
          • M Marcus J Smith

            Pete O`Hanlon wrote:

            KISS

            Yeah I wish people would remember that...dangit!


            CleaKO

            "I think you'll be okay here, they have a thin candy shell. 'Surprised you didn't know that.'" - Tommy (Tommy Boy)
            "Fill it up again! Fill it up again! Once it hits your lips, it's so good!" - Frank the Tank (Old School)

            T Offline
            T Offline
            Tristan Rhodes
            wrote on last edited by
            #5

            KISS - 1) Lots of small, primitive working components that perform a specific task and clip together? 2) Few large complex classes? Which one? [Edit: Typo - Simple = Complex in 2nd option]

            ------------------------------- Carrier Bags - 21st Century Tumbleweed.

            P P 2 Replies Last reply
            0
            • T Todd_s02

              I was never one for the intricacies of the C preprocessor. On my latest project, apparently (or rather, unfortunately) someone is. An .h file has a bunch of definitions (real variable names changed to protect the innocent): statedefs.h: makeState(State1, 0x01) makeState(State2, 0x02) makeState(State3, 0x03) Odd, I think, but ok. Then I go look up "makeState". What the... 3 entries? That's not a good sign. Instance 1: #define makeState(NAME, NUM) ST_##NAME## = ##NUM##, typedef enum { #include "statedefs.h" ST_LAST } statetype; Instance 2: Embedded in the middle of a function(!) #undef makestate #define makeState(NAME, NUM) somevariable++; #include "statedefs.h" Instance 3: #define makestate(NAME, NUM) { "ST_"#NAME,0,0}, sometype stateinfo[] = { #include "statedefs.h" } There are no external programs being used, no weird autogeneration stuff.. the entire set of code is a replacement for: enum { ST_State1 = 1, ST_State2 = 2, ST_State3 = 3, ST_LAST } Most editors I've tried cannot tag it, due to the preprocessor concatenation used ("##" in instance 1). References don't work either. And this is one of the easier to read examples of preprocessor abuse... I just try and remind myself that code written this way makes it that much easier on my next job interview!

              P Offline
              P Offline
              peterchen
              wrote on last edited by
              #6

              somestateinfo gives you literal strings for the names, so it's a replacement for:

              enum
              {
              ST_State1 = 1,
              ST_State2 = 2,
              ST_State3 = 3,

              ST_LAST
              }

              sometype stateinfo[] =
              {
              { "ST_State1", 0, 0 },
              { "ST_State2", 0, 0 },
              { "ST_State2", 0, 0 },
              }

              If he'd used, say, #define makestate(NAME, NUM) { "ST_"#NAME,NUM,0}, you could derive a name-value mapping for enums. It could even remove a prefix from the enum constant. The "inside a function" counts the values actually defined, which would be better derived from sizeof(stateinfo)/sizeof(stateinfo[0]) Not that I ever endorse such conding practices :rolleyes: But it's a not-to-unusual way around lack of reflection in C / C++.


              We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
              My first real C# project | Linkify!|FoldWithUs! | sighist

              P 1 Reply Last reply
              0
              • P peterchen

                somestateinfo gives you literal strings for the names, so it's a replacement for:

                enum
                {
                ST_State1 = 1,
                ST_State2 = 2,
                ST_State3 = 3,

                ST_LAST
                }

                sometype stateinfo[] =
                {
                { "ST_State1", 0, 0 },
                { "ST_State2", 0, 0 },
                { "ST_State2", 0, 0 },
                }

                If he'd used, say, #define makestate(NAME, NUM) { "ST_"#NAME,NUM,0}, you could derive a name-value mapping for enums. It could even remove a prefix from the enum constant. The "inside a function" counts the values actually defined, which would be better derived from sizeof(stateinfo)/sizeof(stateinfo[0]) Not that I ever endorse such conding practices :rolleyes: But it's a not-to-unusual way around lack of reflection in C / C++.


                We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
                My first real C# project | Linkify!|FoldWithUs! | sighist

                P Offline
                P Offline
                PIEBALDconsult
                wrote on last edited by
                #7

                I'm just trying to figure out how I'd do this. I never liked having an enum and a separate string array that had to be kept in sync. I learned some more about the "C preprocessor" today. More reason to like C#

                P 1 Reply Last reply
                0
                • P PIEBALDconsult

                  I'm just trying to figure out how I'd do this. I never liked having an enum and a separate string array that had to be kept in sync. I learned some more about the "C preprocessor" today. More reason to like C#

                  P Offline
                  P Offline
                  peterchen
                  wrote on last edited by
                  #8

                  I think the best thing would be an Excel sheet (or similar) and a code generator that is included in the build process.


                  We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
                  My first real C# project | Linkify!|FoldWithUs! | sighist

                  P 1 Reply Last reply
                  0
                  • T Tristan Rhodes

                    KISS - 1) Lots of small, primitive working components that perform a specific task and clip together? 2) Few large complex classes? Which one? [Edit: Typo - Simple = Complex in 2nd option]

                    ------------------------------- Carrier Bags - 21st Century Tumbleweed.

                    P Offline
                    P Offline
                    peterchen
                    wrote on last edited by
                    #9

                    You got something here! At a certain point, complexity can be moved around between "participants", but it remains in the project. "clipping components together" can increase complexity by one (thinking on a logarithmic scale) If your target is, however, still two or three orders of complexity away, you are in trouble. I think the idea is to plug together the next layer's "small, primitive classes" from the layer below. However, plugging components may give you the robustness of an application, but components have much higher requirements to be pluggable. At each layer, you spend more and more glue code to fit things together. It helps to start with a "more skilled", higher level language (i.e. start at higher complexity already, so the gap gets smaller), or apply KISS to the project goals (but that's not always possible). Hmmm... no solution, nope.


                    We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
                    My first real C# project | Linkify!|FoldWithUs! | sighist

                    T 1 Reply Last reply
                    0
                    • T Tristan Rhodes

                      KISS - 1) Lots of small, primitive working components that perform a specific task and clip together? 2) Few large complex classes? Which one? [Edit: Typo - Simple = Complex in 2nd option]

                      ------------------------------- Carrier Bags - 21st Century Tumbleweed.

                      P Offline
                      P Offline
                      Pete OHanlon
                      wrote on last edited by
                      #10

                      Complexity does not necessarily contradict the KISS principle. Many problems are complex, but the constituent parts to the solution should be as simple as possible to solve the problem.

                      Deja View - the feeling that you've seen this post before.

                      1 Reply Last reply
                      0
                      • P peterchen

                        I think the best thing would be an Excel sheet (or similar) and a code generator that is included in the build process.


                        We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
                        My first real C# project | Linkify!|FoldWithUs! | sighist

                        P Offline
                        P Offline
                        PIEBALDconsult
                        wrote on last edited by
                        #11

                        I'm now pondering storing the values in XML and using XSLT to create the h file. XSLT: the new C Preprocessor

                        D P 2 Replies Last reply
                        0
                        • P PIEBALDconsult

                          I'm now pondering storing the values in XML and using XSLT to create the h file. XSLT: the new C Preprocessor

                          D Offline
                          D Offline
                          Dan Neely
                          wrote on last edited by
                          #12

                          that'd be worthy of a fresh thread here in and of itself.

                          -- CleaKO The sad part about this instance is that none of the users ever said anything [about the problem]. Pete O`Hanlon Doesn't that just tell you everything you need to know about users?

                          P 1 Reply Last reply
                          0
                          • P PIEBALDconsult

                            I'm now pondering storing the values in XML and using XSLT to create the h file. XSLT: the new C Preprocessor

                            P Offline
                            P Offline
                            peterchen
                            wrote on last edited by
                            #13

                            I actually wanted to do that as a project to "learn XML", but just the basics were such a bumpy ride that I contracted some kind of XML allergy. So if you do: A R T I C L E ! ;)


                            We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
                            My first real C# project | Linkify!|FoldWithUs! | sighist

                            P 2 Replies Last reply
                            0
                            • D Dan Neely

                              that'd be worthy of a fresh thread here in and of itself.

                              -- CleaKO The sad part about this instance is that none of the users ever said anything [about the problem]. Pete O`Hanlon Doesn't that just tell you everything you need to know about users?

                              P Offline
                              P Offline
                              PIEBALDconsult
                              wrote on last edited by
                              #14

                              Correct you are, but should I? Or should it go in, perhaps, the XML/XSL forum? Or an article? Aw heck, here it is, you decide: state.xml

                              <state Prefix="ST_" Type="sometype" >
                              <State1>0x01</State1>
                              <State2>0x02</State2>
                              <State3>0x03</State3>
                              </state>

                              state.xsl

                              <?xml version="1.0" encoding="ISO-8859-1"?>
                              <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
                              <xsl:output omit-xml-declaration="yes" method="text"/>
                              <xsl:template match="/">
                              <xsl:for-each select="*">
                              typedef enum {
                              <xsl:for-each select="*">
                              <xsl:value-of select="../@Prefix"/><xsl:value-of select="name()"/>=<xsl:value-of select="."/>,
                              <xsl:if test="position()=last()"><xsl:value-of select="../@Prefix"/>LAST=<xsl:value-of select="last()"/></xsl:if>
                              </xsl:for-each>} <xsl:value-of select="name()"/>type ;
                              <xsl:value-of select="@Type"/>xsl:text </xsl:text><xsl:value-of select="name()"/>info[] = {
                              <xsl:for-each select="*">
                              <xsl:if test="position()!=1">,</xsl:if>{"<xsl:value-of select="../@Prefix"/><xsl:value-of select="name()"/>",0,0}
                              </xsl:for-each>}
                              </xsl:for-each>
                              </xsl:template>
                              </xsl:stylesheet>

                              result

                                typedef enum {
                                ST\_State1=0x01,
                                  ST\_State2=0x02,
                                  ST\_State3=0x03,
                                  ST\_LAST=3} statetype ;
                                sometype stateinfo\[\] = {
                                {"ST\_State1",0,0}
                                ,{"ST\_State2",0,0}
                                ,{"ST\_State3",0,0}
                                }
                              

                              As mentioned elsewhere, the counting of the entries in part two is unnecessary, but notice that here I set the value of ST_LAST to the number of entries.

                              D 1 Reply Last reply
                              0
                              • P peterchen

                                I actually wanted to do that as a project to "learn XML", but just the basics were such a bumpy ride that I contracted some kind of XML allergy. So if you do: A R T I C L E ! ;)


                                We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
                                My first real C# project | Linkify!|FoldWithUs! | sighist

                                P Offline
                                P Offline
                                PIEBALDconsult
                                wrote on last edited by
                                #15

                                Be careful what you ask for.

                                A 1 Reply Last reply
                                0
                                • P PIEBALDconsult

                                  Correct you are, but should I? Or should it go in, perhaps, the XML/XSL forum? Or an article? Aw heck, here it is, you decide: state.xml

                                  <state Prefix="ST_" Type="sometype" >
                                  <State1>0x01</State1>
                                  <State2>0x02</State2>
                                  <State3>0x03</State3>
                                  </state>

                                  state.xsl

                                  <?xml version="1.0" encoding="ISO-8859-1"?>
                                  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
                                  <xsl:output omit-xml-declaration="yes" method="text"/>
                                  <xsl:template match="/">
                                  <xsl:for-each select="*">
                                  typedef enum {
                                  <xsl:for-each select="*">
                                  <xsl:value-of select="../@Prefix"/><xsl:value-of select="name()"/>=<xsl:value-of select="."/>,
                                  <xsl:if test="position()=last()"><xsl:value-of select="../@Prefix"/>LAST=<xsl:value-of select="last()"/></xsl:if>
                                  </xsl:for-each>} <xsl:value-of select="name()"/>type ;
                                  <xsl:value-of select="@Type"/>xsl:text </xsl:text><xsl:value-of select="name()"/>info[] = {
                                  <xsl:for-each select="*">
                                  <xsl:if test="position()!=1">,</xsl:if>{"<xsl:value-of select="../@Prefix"/><xsl:value-of select="name()"/>",0,0}
                                  </xsl:for-each>}
                                  </xsl:for-each>
                                  </xsl:template>
                                  </xsl:stylesheet>

                                  result

                                    typedef enum {
                                    ST\_State1=0x01,
                                      ST\_State2=0x02,
                                      ST\_State3=0x03,
                                      ST\_LAST=3} statetype ;
                                    sometype stateinfo\[\] = {
                                    {"ST\_State1",0,0}
                                    ,{"ST\_State2",0,0}
                                    ,{"ST\_State3",0,0}
                                    }
                                  

                                  As mentioned elsewhere, the counting of the entries in part two is unnecessary, but notice that here I set the value of ST_LAST to the number of entries.

                                  D Offline
                                  D Offline
                                  Dan Neely
                                  wrote on last edited by
                                  #16

                                  I call a WTF!:laugh:

                                  -- CleaKO The sad part about this instance is that none of the users ever said anything [about the problem]. Pete O`Hanlon Doesn't that just tell you everything you need to know about users?

                                  P 1 Reply Last reply
                                  0
                                  • P peterchen

                                    You got something here! At a certain point, complexity can be moved around between "participants", but it remains in the project. "clipping components together" can increase complexity by one (thinking on a logarithmic scale) If your target is, however, still two or three orders of complexity away, you are in trouble. I think the idea is to plug together the next layer's "small, primitive classes" from the layer below. However, plugging components may give you the robustness of an application, but components have much higher requirements to be pluggable. At each layer, you spend more and more glue code to fit things together. It helps to start with a "more skilled", higher level language (i.e. start at higher complexity already, so the gap gets smaller), or apply KISS to the project goals (but that's not always possible). Hmmm... no solution, nope.


                                    We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
                                    My first real C# project | Linkify!|FoldWithUs! | sighist

                                    T Offline
                                    T Offline
                                    Tristan Rhodes
                                    wrote on last edited by
                                    #17

                                    From my experience, combining the smallest atomic parts together to create another simple atomic part is simply part of good system design. I've encountered HUGE function classes which have masses of dependancies on other stuff and it's a complete nightmare to figure out. At least with lots of small components you can black box at each level and the whole system becomes that much simpler to comprehend. T

                                    ------------------------------- Carrier Bags - 21st Century Tumbleweed.

                                    1 Reply Last reply
                                    0
                                    • D Dan Neely

                                      I call a WTF!:laugh:

                                      -- CleaKO The sad part about this instance is that none of the users ever said anything [about the problem]. Pete O`Hanlon Doesn't that just tell you everything you need to know about users?

                                      P Offline
                                      P Offline
                                      PIEBALDconsult
                                      wrote on last edited by
                                      #18

                                      What's your alternative of choice?

                                      1 Reply Last reply
                                      0
                                      • P PIEBALDconsult

                                        Be careful what you ask for.

                                        A Offline
                                        A Offline
                                        Anton Afanasyev
                                        wrote on last edited by
                                        #19

                                        PIEBALDconsult wrote:

                                        Be careful what you ask for.

                                        I believe this actually is a case where he wants to get what he wishes for..


                                        :badger:

                                        P 1 Reply Last reply
                                        0
                                        • A Anton Afanasyev

                                          PIEBALDconsult wrote:

                                          Be careful what you ask for.

                                          I believe this actually is a case where he wants to get what he wishes for..


                                          :badger:

                                          P Offline
                                          P Offline
                                          PIEBALDconsult
                                          wrote on last edited by
                                          #20

                                          (He's probably the only one.)

                                          P 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