开发者

Are empty macro arguments legal in C++11?

开发者 https://www.devze.com 2023-04-10 18:05 出处:网络
I sometimes deliberately omit macro arguments. For example, for a function-like macro like #define MY_MACRO(A, B, C)...

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 t开发者_JAVA百科he "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_)


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.


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.


When I do that I normally put a comment in place of the argument.

Place a macro that will be expanded to the empty string.

#define NOARG
...
MY_MACRO(/*Ignore this Param*/ NOARG, bar, baz)

PS. I got no warning with g++ with or without the -std=c++98 flag.

  • g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
  • g++ (Apple Inc. build 5666) 4.2.1
0

精彩评论

暂无评论...
验证码 换一张
取 消