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. The Lounge
  3. This, this right here... is why people hate macros...

This, this right here... is why people hate macros...

Scheduled Pinned Locked Moved The Lounge
23 Posts 10 Posters 2 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.
  • J Jeremy Falcon

    Bruh

    #define SUBMIT_FIELD(p) \
    do { \
    if (!quoted) \
    entry_pos -= spaces; \
    if (p->options & CSV_APPEND_NULL) \
    ((p)->entry_buf[entry_pos]) = '\0'; \
    if (cb1 && (p->options & CSV_EMPTY_IS_NULL) && !quoted && entry_pos == 0) \
    cb1(NULL, entry_pos, data); \
    else if (cb1) \
    cb1(p->entry_buf, entry_pos, data); \
    pstate = FIELD_NOT_BEGUN; \
    entry_pos = quoted = spaces = 0; \
    } while (0)

    I mean dude, make it an inline function already. :laugh:

    Jeremy Falcon

    B Offline
    B Offline
    BernardIE5317
    wrote on last edited by
    #8

    Would the call to the inline function be "submitField(p, quoted, entry_pos, spaces, entry_buf, cb1, data, pstate);"?

    1 Reply Last reply
    0
    • J Jeremy Falcon

      Bruh

      #define SUBMIT_FIELD(p) \
      do { \
      if (!quoted) \
      entry_pos -= spaces; \
      if (p->options & CSV_APPEND_NULL) \
      ((p)->entry_buf[entry_pos]) = '\0'; \
      if (cb1 && (p->options & CSV_EMPTY_IS_NULL) && !quoted && entry_pos == 0) \
      cb1(NULL, entry_pos, data); \
      else if (cb1) \
      cb1(p->entry_buf, entry_pos, data); \
      pstate = FIELD_NOT_BEGUN; \
      entry_pos = quoted = spaces = 0; \
      } while (0)

      I mean dude, make it an inline function already. :laugh:

      Jeremy Falcon

      G Offline
      G Offline
      Gary Wheeler
      wrote on last edited by
      #9

      I do believe the technical term is 'ick'.

      Software Zen: delete this;

      1 Reply Last reply
      0
      • J Jeremy Falcon

        Bruh

        #define SUBMIT_FIELD(p) \
        do { \
        if (!quoted) \
        entry_pos -= spaces; \
        if (p->options & CSV_APPEND_NULL) \
        ((p)->entry_buf[entry_pos]) = '\0'; \
        if (cb1 && (p->options & CSV_EMPTY_IS_NULL) && !quoted && entry_pos == 0) \
        cb1(NULL, entry_pos, data); \
        else if (cb1) \
        cb1(p->entry_buf, entry_pos, data); \
        pstate = FIELD_NOT_BEGUN; \
        entry_pos = quoted = spaces = 0; \
        } while (0)

        I mean dude, make it an inline function already. :laugh:

        Jeremy Falcon

        C Offline
        C Offline
        charlieg
        wrote on last edited by
        #10

        Put your man pants on... Charlie is in the room. Doing something like this is evil, not acceptable and pure unsupportable garbage. I call it whiz kid code. When the kid moves on, or dies (whiz kids are getting older) the FIRST thing that will happen is a lot of cussing. The second thing that will happen is this will get tossed into a function - screw the inline nonsense. I'm not even sure that's relevant anymore unless you are in a restricted embedded environment. It's not supportable, you cannot debug it, why the f*** would you do this? Because you want to be cute. Show your macro balls. You need to be taken to the back parking lot and beat on. The next time you think to do this (and I've actually seen worse) your eye will start to twitch and your right hand tremble...

        Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

        H B 2 Replies Last reply
        0
        • P Peter_in_2780

          Does it predate C99, when inline first hit C?

          Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012

          J Offline
          J Offline
          Jeremy Falcon
          wrote on last edited by
          #11

          Good question. I think it was written in C89.

          Jeremy Falcon

          1 Reply Last reply
          0
          • J Jeremy Falcon

            Bruh

            #define SUBMIT_FIELD(p) \
            do { \
            if (!quoted) \
            entry_pos -= spaces; \
            if (p->options & CSV_APPEND_NULL) \
            ((p)->entry_buf[entry_pos]) = '\0'; \
            if (cb1 && (p->options & CSV_EMPTY_IS_NULL) && !quoted && entry_pos == 0) \
            cb1(NULL, entry_pos, data); \
            else if (cb1) \
            cb1(p->entry_buf, entry_pos, data); \
            pstate = FIELD_NOT_BEGUN; \
            entry_pos = quoted = spaces = 0; \
            } while (0)

            I mean dude, make it an inline function already. :laugh:

            Jeremy Falcon

            R Offline
            R Offline
            Rick York
            wrote on last edited by
            #12

            I have done something like this just a few times and I remember them fairly clearly. One was because of performance reasons and the other was because C does not have templates. This does not appear to be either case. In fact, it's a single-pass pseudo-loop. I have done that too but never in a macro and never when there wasn't at least a few breaks in the "loop." I see no good reasons at all for this monstrosity.

            "They have a consciousness, they have a life, they have a soul! Damn you! Let the rabbits wear glasses! Save our brothers! Can I get an amen?"

            J 1 Reply Last reply
            0
            • C charlieg

              Put your man pants on... Charlie is in the room. Doing something like this is evil, not acceptable and pure unsupportable garbage. I call it whiz kid code. When the kid moves on, or dies (whiz kids are getting older) the FIRST thing that will happen is a lot of cussing. The second thing that will happen is this will get tossed into a function - screw the inline nonsense. I'm not even sure that's relevant anymore unless you are in a restricted embedded environment. It's not supportable, you cannot debug it, why the f*** would you do this? Because you want to be cute. Show your macro balls. You need to be taken to the back parking lot and beat on. The next time you think to do this (and I've actually seen worse) your eye will start to twitch and your right hand tremble...

              Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

              H Offline
              H Offline
              honey the codewitch
              wrote on last edited by
              #13

              You did mention embedded, so I am commenting in light of that. My experience on embedded is the damned GCC compiler does not like to inline your functions unless they're extremely trivial. Even if you put "inline" In fact I treat "inline" strictly as a linker flag. It tells the linker to just use the first implementation it finds. Good for header only libraries. Inline isn't good for much else. There's a compiler extension attribute to force a function to be inline in GCC. I've had to use it before. I don't know when it was introduced. So absent that attribute, such a macro may be necessary. I've seen it in TFT_eSPI code as well, on the performance critical paths. I'm pretty sure this is why. Edit: I don't think this is the case with the code in the OP. I'm speaking generally about this technique.

              Check out my IoT graphics library here: https://honeythecodewitch.com/gfx And my IoT UI/User Experience library here: https://honeythecodewitch.com/uix

              C 1 Reply Last reply
              0
              • H honey the codewitch

                You did mention embedded, so I am commenting in light of that. My experience on embedded is the damned GCC compiler does not like to inline your functions unless they're extremely trivial. Even if you put "inline" In fact I treat "inline" strictly as a linker flag. It tells the linker to just use the first implementation it finds. Good for header only libraries. Inline isn't good for much else. There's a compiler extension attribute to force a function to be inline in GCC. I've had to use it before. I don't know when it was introduced. So absent that attribute, such a macro may be necessary. I've seen it in TFT_eSPI code as well, on the performance critical paths. I'm pretty sure this is why. Edit: I don't think this is the case with the code in the OP. I'm speaking generally about this technique.

                Check out my IoT graphics library here: https://honeythecodewitch.com/gfx And my IoT UI/User Experience library here: https://honeythecodewitch.com/uix

                C Offline
                C Offline
                charlieg
                wrote on last edited by
                #14

                fair enough, yet in all my years, I have yet to see a significant (key word there) performance improvement doing macros like this. Nor have I seen a test process to validate the macro. I'm more in line with the "hey, looks like it works!" and people move on. I've not used gcc much, but 99% of the time, inefficiency is caused by poor choices and algorithms. People mallocing 10MB "just in case" when the structure is only 16k. I had a sequential loop through a 10 key structure array. I thought to myself "hmm, let's try a hash lookup from stl, it should be faster." Nope, 5x slower. Okay, lets not do that. But go back to my original point - ignore the compiler making this more efficient, how would you possibly debug that macro?

                Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

                H 1 Reply Last reply
                0
                • C charlieg

                  fair enough, yet in all my years, I have yet to see a significant (key word there) performance improvement doing macros like this. Nor have I seen a test process to validate the macro. I'm more in line with the "hey, looks like it works!" and people move on. I've not used gcc much, but 99% of the time, inefficiency is caused by poor choices and algorithms. People mallocing 10MB "just in case" when the structure is only 16k. I had a sequential loop through a 10 key structure array. I thought to myself "hmm, let's try a hash lookup from stl, it should be faster." Nope, 5x slower. Okay, lets not do that. But go back to my original point - ignore the compiler making this more efficient, how would you possibly debug that macro?

                  Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

                  H Offline
                  H Offline
                  honey the codewitch
                  wrote on last edited by
                  #15

                  What I would do is like I did for TFT_eSPI. Put the code into routines, and then switch out the macro instantiations to calls to the routine. It's a little work, but mostly just editor search and replace. I will forgive TFT_eSPI for this code. I checked the output at godbolt.org . Those macros do what they're supposed to. Specifically, they write various types of data to an SPI bus very quickly. It's inherently low level. The library code that builds on it could be cleaner, but is nowhere near as unintelligible.

                  Check out my IoT graphics library here: https://honeythecodewitch.com/gfx And my IoT UI/User Experience library here: https://honeythecodewitch.com/uix

                  1 Reply Last reply
                  0
                  • R Rick York

                    I have done something like this just a few times and I remember them fairly clearly. One was because of performance reasons and the other was because C does not have templates. This does not appear to be either case. In fact, it's a single-pass pseudo-loop. I have done that too but never in a macro and never when there wasn't at least a few breaks in the "loop." I see no good reasons at all for this monstrosity.

                    "They have a consciousness, they have a life, they have a soul! Damn you! Let the rabbits wear glasses! Save our brothers! Can I get an amen?"

                    J Offline
                    J Offline
                    Jeremy Falcon
                    wrote on last edited by
                    #16

                    Rick York wrote:

                    I have done something like this just a few times and I remember them fairly clearly.

                    Don't worry, Rick. We won't tell anyone. :laugh:

                    Rick York wrote:

                    I see no good reasons at all for this monstrosity.

                    Same. Peter (above) mentioned a good point, the code was written in C89 before the inline keyword. So, can only guess it was for performance. Personally, I think I would've taken the performance hit of a function call. Assuming it was written in the 90s due to C89... a function call wasn't _that_ bad IMO.

                    Jeremy Falcon

                    1 Reply Last reply
                    0
                    • C charlieg

                      Put your man pants on... Charlie is in the room. Doing something like this is evil, not acceptable and pure unsupportable garbage. I call it whiz kid code. When the kid moves on, or dies (whiz kids are getting older) the FIRST thing that will happen is a lot of cussing. The second thing that will happen is this will get tossed into a function - screw the inline nonsense. I'm not even sure that's relevant anymore unless you are in a restricted embedded environment. It's not supportable, you cannot debug it, why the f*** would you do this? Because you want to be cute. Show your macro balls. You need to be taken to the back parking lot and beat on. The next time you think to do this (and I've actually seen worse) your eye will start to twitch and your right hand tremble...

                      Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

                      B Offline
                      B Offline
                      BernardIE5317
                      wrote on last edited by
                      #17

                      Greetings Kind Regards May I please inquire the alternative. I do not see how a function inline or not would be sufficient as the macro is referencing many local variables. All those terms of course can be passed to a function but now you have an ugly function call. In my own current project a number of methods perform identical logic utilizing local variables of identical name as part of their different duties. Though the macro itself is ugly has heck and difficult to debug the aforementioned methods are much cleaner in appearance. I would be happy and eager to learn of a superior method. Thank You Kindly

                      N C 3 Replies Last reply
                      0
                      • B BernardIE5317

                        Greetings Kind Regards May I please inquire the alternative. I do not see how a function inline or not would be sufficient as the macro is referencing many local variables. All those terms of course can be passed to a function but now you have an ugly function call. In my own current project a number of methods perform identical logic utilizing local variables of identical name as part of their different duties. Though the macro itself is ugly has heck and difficult to debug the aforementioned methods are much cleaner in appearance. I would be happy and eager to learn of a superior method. Thank You Kindly

                        N Offline
                        N Offline
                        Niels Holst
                        wrote on last edited by
                        #18

                        You are absolutely right. In C++ you could make this an inline member function and turn all those local variables into member variables. That would make it a clean function call with the struct as a single parameter. Hmm, in C you could possible package all those local variables into a local struct which could then be passed as a single argument to in inline function?

                        B 1 Reply Last reply
                        0
                        • N Niels Holst

                          You are absolutely right. In C++ you could make this an inline member function and turn all those local variables into member variables. That would make it a clean function call with the struct as a single parameter. Hmm, in C you could possible package all those local variables into a local struct which could then be passed as a single argument to in inline function?

                          B Offline
                          B Offline
                          BernardIE5317
                          wrote on last edited by
                          #19

                          Thank you for your kind and helpful reply. A perfect solution is now obvious id est package as you described then hide package and inline call via macro. Voila Presto Bingo. A single term exempli gratia CALL_GREAT_CODE_HERE_BEHIND_THIS_MACRO This is why I love macros.

                          1 Reply Last reply
                          0
                          • B BernardIE5317

                            Greetings Kind Regards May I please inquire the alternative. I do not see how a function inline or not would be sufficient as the macro is referencing many local variables. All those terms of course can be passed to a function but now you have an ugly function call. In my own current project a number of methods perform identical logic utilizing local variables of identical name as part of their different duties. Though the macro itself is ugly has heck and difficult to debug the aforementioned methods are much cleaner in appearance. I would be happy and eager to learn of a superior method. Thank You Kindly

                            C Offline
                            C Offline
                            charlieg
                            wrote on last edited by
                            #20

                            The alleged argument is that the macro makes code easier to read and is more efficient. Reading: sure, if you wrote the macro it's perfectly clear in YOUR head what is does. But you cannot debug it. You are embedding a time bomb in your code for support. But wtf cares about support and long term issues? I argue this just creates additional code entropy. Efficiency: prove it. I'm going to write on my whiteboard to start a project. If you write macros like this, because it makes the code run faster - prove it. In 45 years of coding, we're dealing with 0.01% of issues, if that. Modern compilers are modern. Well, I hope gcc is. The real danger has to do with what is behind the compiler. Add in one dll from MS and all of your macros are screwed. Meanwhile you have the support legacy of this macro noise. If you are going to complicate your code, justify it. Otherwise, stop screwing the poor slob who comes along 5 years later.

                            Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

                            1 Reply Last reply
                            0
                            • J Jeremy Falcon

                              Bruh

                              #define SUBMIT_FIELD(p) \
                              do { \
                              if (!quoted) \
                              entry_pos -= spaces; \
                              if (p->options & CSV_APPEND_NULL) \
                              ((p)->entry_buf[entry_pos]) = '\0'; \
                              if (cb1 && (p->options & CSV_EMPTY_IS_NULL) && !quoted && entry_pos == 0) \
                              cb1(NULL, entry_pos, data); \
                              else if (cb1) \
                              cb1(p->entry_buf, entry_pos, data); \
                              pstate = FIELD_NOT_BEGUN; \
                              entry_pos = quoted = spaces = 0; \
                              } while (0)

                              I mean dude, make it an inline function already. :laugh:

                              Jeremy Falcon

                              S Offline
                              S Offline
                              Stacy Dudovitz
                              wrote on last edited by
                              #21

                              That's why function templates were created in C++. All of the compile time features without adding overhead or degradation in execution speed. When I am coding in C++, I *rarely* use/utilize macros. Which isn't to say that macros, properly implemented aren't useful. Take, example, the need to "stringize" a set of characters. You can't really beat: #define STRINGIZE(x) #x :) One more thing... too often, macros are used to provide some way to represent a value, as opposed to using a const variable declaration. One should eschew this: #define PI 3.1415927f in favor of this: const float PI = 3.1415927f;

                              J 1 Reply Last reply
                              0
                              • S Stacy Dudovitz

                                That's why function templates were created in C++. All of the compile time features without adding overhead or degradation in execution speed. When I am coding in C++, I *rarely* use/utilize macros. Which isn't to say that macros, properly implemented aren't useful. Take, example, the need to "stringize" a set of characters. You can't really beat: #define STRINGIZE(x) #x :) One more thing... too often, macros are used to provide some way to represent a value, as opposed to using a const variable declaration. One should eschew this: #define PI 3.1415927f in favor of this: const float PI = 3.1415927f;

                                J Offline
                                J Offline
                                Jeremy Falcon
                                wrote on last edited by
                                #22

                                1,000% agree. To be honest, my C++ is weak. I've always done "C in C++" but maybe it's time I revisit that.

                                Jeremy Falcon

                                1 Reply Last reply
                                0
                                • B BernardIE5317

                                  Greetings Kind Regards May I please inquire the alternative. I do not see how a function inline or not would be sufficient as the macro is referencing many local variables. All those terms of course can be passed to a function but now you have an ugly function call. In my own current project a number of methods perform identical logic utilizing local variables of identical name as part of their different duties. Though the macro itself is ugly has heck and difficult to debug the aforementioned methods are much cleaner in appearance. I would be happy and eager to learn of a superior method. Thank You Kindly

                                  C Offline
                                  C Offline
                                  charlieg
                                  wrote on last edited by
                                  #23

                                  appearance has nothing to do with test, maintainability and understanding. Don't get me wrong, there is a place for macros - SIMPLE macros. I'll get silly, I can take a function at 1000 lines and turn it into a macro. How is that helpful? #define _DO_STUFF_ No. Sorry, just no. Modern compilers are efficient. People that write huge macros are either using their preferences, trying to be cute, or have never been held accountable. It's a disease, get therapy.

                                  Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

                                  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