Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are empty macro arguments legal in C++11?

Tags:

c++

c++11

macros

I sometimes deliberately omit macro arguments. For example, for a function-like macro like

#define MY_MACRO(A, B, C)  ... 

I might call it as:

MY_MACRO(, bar, baz) 

There are still technically 3 arguments; it's just that the first one is "empty". This question is not about variadic macros.

When I do this I get warnings from g++ when compiling with -ansi (aka -std=c++98), but not when I use -std=c++0x. Does this mean that empty macro args are legal in the new C++ standard?

That's the entirety of my question, but anticipating the "why would you want to?" response, here's an example. I like keeping .h files uncluttered by function bodies, but implementing simple accessors outside of the .h file is tedious. I therefore wrote the following macro:

#define IMPLEMENT_ACCESSORS(TEMPLATE_DECL, RETURN_TYPE, CLASS, FUNCTION, MEMBER) \   TEMPLATE_DECL                                                         \   inline RETURN_TYPE* CLASS::Mutable##FUNCTION() {                      \     return &MEMBER;                                                     \   }                                                                     \                                                                         \   TEMPLATE_DECL                                                         \   inline const RETURN_TYPE& CLASS::FUNCTION() const {                   \     return MEMBER;                                                      \   } 

This is how I would use it for a class template that contains an int called int_:

IMPLEMENT_ACCESSORS(template<typename T>, int, MyTemplate<T>, Int, int_) 

For a non-template class, I don't need template<typename T>, so I omit that macro argument:

IMPLEMENT_ACCESORS(, int, MyClass, Int, int_) 
like image 501
SuperElectric Avatar asked Oct 05 '11 19:10

SuperElectric


People also ask

Which is a valid type of arguments in macro?

There are two types of arguments: keyword and positional. Keyword arguments are assigned names in the macro definition; in the macro call, they are identified by name.

What does empty macro?

It is simply a macro that expands to, well, nothing.

Can we pass arguments in macro?

A parameter can be either a simple string or a quoted string. It can be passed by using the standard method of putting variables into shared and profile pools (use VPUT in dialogs and VGET in initial macros).

How many arguments macro can have in C?

For portability, you should not have more than 31 parameters for a macro. The parameter list may end with an ellipsis (...).


2 Answers

If I understand correctly, empty macro argument is allowed since C99 and C++0x(11).
C99 6.10.3/4 says:

... the number of arguments (including those arguments consisting of no preprocessing tokens) shall equal the number of parameters ...

and C++ N3290 16.3/4 has the same statement, while C++03 16.3/10 mentions:

... any argument consists of no preprocessing tokens, the behavior is undefined.

I think empty argument comes under the representation arguments consisting of no preprocessing tokens above.
Also, 6.10.3 in Rationale for International Standard Programming Languages C rev. 5.10 says:

A new feature of C99: Function-like macro invocations may also now have empty arguments, that is, an argument may consist of no preprocessing tokens.

like image 167
Ise Wisteria Avatar answered Oct 07 '22 09:10

Ise Wisteria


Yes. The relevant bit is 16.3/11

The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens.

There's no requirement that a single argument corresponds to precisely one token. In fact, the following section makes it clear that there can be more than one token per argument:

Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file

In your case, one argument happens to correspond to zero tokens. That doesn't cause any contradiction.

[edit] This was changed by N1566 to bring C++11 in line with C99.

like image 44
MSalters Avatar answered Oct 07 '22 09:10

MSalters