0

I want a macro that declares an int with a given name and optional initializer expression.

I tried using this answer on Stack Overflow but with no success.

This is what I tried:

#define macro(...) int FIRST(__VA_ARGS__)(REST(__VA_ARGS__))

when used like this there are no problems:

macro(foo);

but when given an initializer there are errors:

macro(foo, 42);

The alternative - of just using __VA_ARGS__ gives a warning from -pedantic in GCC when there are no arguments.

How can I fix this?

And is it also possible to avoid the () braces when there is no initializer expression - meaning no zero initialization but default?

Note that my real use case is not just for int but for any type and using a third party like boost is not an option.

Community
  • 1
  • 1
onqtam
  • 4,356
  • 2
  • 28
  • 50
  • 3
    Using macros is something very few recommends as they tend to obfuscate code. Can you perhaps elaborate on the *original* problem you try to solve with this solution? *Why* are you using macros this way? Perhaps there are other ways to solve you solution, ways that doesn't depend on macros? – Some programmer dude Mar 20 '17 at 10:28
  • 1
    You can fix this by actually writing C++ code, instead of attempting to use this kind of a crufty, obsolete C syntax, and by using templates; which is the correct way to do this in C++. This is a very broad topic, not suitable for a brief answer; so what you need to do is open your C++ to the chapter that talks about templates, and start reading. – Sam Varshavchik Mar 20 '17 at 10:29
  • C++ is not powerful enough and thus I need to resort to macros for code generation. Thousands of projects depend on the preprocessor. I understand that this is not a pleasant problem to solve but I'm just asking for help - if I don't get it - its fine. – onqtam Mar 20 '17 at 10:30
  • 1
    What is the point to do a macro for this use case?? `int foo=42;` is more explicit. – Oliv Mar 20 '17 at 10:33
  • 4
    How do you *know* C++ "is not powerful enough"? How do *we* know? Your question is an example of [the XY problem](http://xyproblem.info/), where you tell us about a solution you want fixed, but don't tell us what the solution is supposed to solve. And just because thousands of projects uses macros in a possible bad way doesn't mean you have to do the same. – Some programmer dude Mar 20 '17 at 10:34
  • C++ is quite powerful enough to me. Templates, with type-safety, will be far more powerful than simple preprocessor tricks. – Sam Varshavchik Mar 20 '17 at 10:35
  • Well this is just a small part of a huge macro which does a lot of things - and this is the final piece of the puzzle I need to solve... So many times I've been told to produce a minimal example - and when I do - the XY problem gets linked... wtf – onqtam Mar 20 '17 at 10:36
  • Well, apart from the macro-ness, you also said _optional constructor arguments_ when `int` doesn't have a constructor (I think you mean _initializer expression_). So, it's reasonable for people to guess you're also mistaken about the need to do it this way. – Useless Mar 20 '17 at 10:43
  • @onqtam: Even if it's part of a huge macro, and for one reason or another that's not replaceable with a template, you still might be better of delegating this particular bit of functionality from the macro to a separate template. – MSalters Mar 20 '17 at 10:43
  • @Useless I will correct that part. – onqtam Mar 20 '17 at 10:48
  • *this is just a small part of a huge macro which does a lot of things*. This alone would frighten me... Macro language is indeed powerful, but also awful to write (syntax) and debug. Most C++ programmers actually think that templates can do much of what was done by macros in C. Maybe you could try to build a C extract of your requirements, and ask it in a new question with the C tag. You could find some *macro geeks* with C tag. – Serge Ballesta Mar 20 '17 at 10:50

2 Answers2

5
#define macro(...) int FIRST(__VA_ARGS__){REST(__VA_ARGS__)}

Your chief problem is that int foo(); is a function declaration. int foo{}; isn't.

MSalters
  • 173,980
  • 10
  • 155
  • 350
0

In the end I ended up with the following: link

I forward the __VA_ARGS__ to a variadic template because my problem wasn't exactly what I described here (as suggested in the comments) - but the problems when not supplying an initializer persisted - so I silenced the warnings in the header for GCC with #pragma GCC system_header and for Clang I used _Pragma() for -Wgnu-zero-variadic-macro-arguments. MSVC wasn't a problem.

I also fell victim to the most vexing parse as @MSalters points out in his answer.

onqtam
  • 4,356
  • 2
  • 28
  • 50