← Back to context

Comment by uecker

12 hours ago

I am not sure. I agree one should minimize macros in C, but for some things a small macro layer still beats the complexity of C++ and is not inferior in my opinion.

C++ templates are far cleaner, easier to debug, and produce more comprehensible errors than C macros. And C++ templates are rightly famous for being terrible at all of the above.

  • Hey, I agree about your second sentence but I do not really see the first. Alone that I can directly inspect the result of the preprocessor makes macros easier to debug than templates in my experience.

    • > I can directly inspect the result of the preprocessor makes macros easier to debug

      Tangential note but: why does this require a separate re-invocation of the compiler with the '-E' flag? Say I have this silly example with a comma instead of the semicolon inside W() macro:

          #define W(a, b)  b, int a
          #define X(a, b)  W(b, a)
      
          int kekw(int x) {
              int z = X(23, k) = x;
              return z + k;
          }
      

      When I shove it into GCC without -E, it says

          <source>: In function 'int kekw(int)':
          <source>:1:21: error: expected unqualified-id before 'int'
              1 | #define W(a, b)  b, int a
                |                     ^~~
          <source>:2:18: note: in expansion of macro 'W'
              2 | #define X(a, b)  W(b, a)
                |                  ^
          <source>:5:13: note: in expansion of macro 'X'
              5 |     int z = X(23, k) = x;
                |             ^
          <source>:6:16: error: 'k' was not declared in this scope
              6 |     return z + k;
                |       
      

      instead of, you know, showing me the expanded text so that I could see what's actually wrong with the generated variable declarations? Something like

          <source>: In function 'int kekw(int)':
          <source>:1:21: error: expected unqualified-id before 'int'
              1 | #define W(a, b)  b, int a
                |                     ^~~
          <source>:2:18: note: in expansion of macro 'W'
              2 | #define X(a, b)  W(b, a)
                |                  ^
          <source>:5:13: note: in expansion of macro 'X'
              5 |     int z = X(23, k) = x;
                |             ^
          <source>:5:-: note: the expanded source text is
                |     int z = 23, int k = x;
                |                 ^~~
          <source>:6:16: error: 'k' was not declared in this scope
              6 |     return z + k;
                |       
      

      perhaps? I understand that tracking the lines/columns inside the expanded text is highly non-trivial (although collapsing them all onto the position of the top-level macro is already just as non-trivial), but still. Show me what the source that you actually can't compile, not the three-steps removed precursor to it — I sure as hell can't expand macros in my head.

      Also, what is this first error message about in the first place? Why the hell does it expect unqualified-id before "int"? If you put "int" after the unqualified-id, it still would be illegal; and an unqualified-id is not the only thing that can follow the comma in this context anyway.

      3 replies →