6

Why can not you use C ++ 11 boot with macros?

 2 years ago
source link: https://www.codesd.com/item/why-can-not-you-use-c-11-boot-with-macros.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Why can not you use C ++ 11 boot with macros?

advertisements

I just discovered that you cannot always use brace initialization when passing arguments to macros. I found this when an ASSERT() macro failed to compile. However, the following example illustrates the problem:

#include <iostream>
#include <string>
using namespace std;

#define PRINT_SIZE( f ) cout << "Size=" << (f).size() << endl;

int main()
{
  PRINT_SIZE( string("ABC") );  // OK, prints: "Size=3"
  PRINT_SIZE( string{"ABC"} );  // OK, prints: "Size=3"

  PRINT_SIZE( string("ABCDEF",3) ); // OK, prints: "Size=3"
  PRINT_SIZE( string{"ABCDEF",3} ); // Error: macro 'PRINT_SIZE' passed 2 arguments, but takes just 1

   return 0;
}

Is there a reason why macros cannot be made to work with brace initialization?

Edit:

I have since discovered that you can also use a variadic macro, and that solves the problem perfectly:

#include <iostream>
#include <string>
using namespace std;

#define PRINT_SIZE( ... ) cout << "Size=" << (__VA_ARGS__).size() << endl;

int main()
{
  PRINT_SIZE( string("ABC") );  // OK, prints: "Size=3"
  PRINT_SIZE( string{"ABC"} );  // OK, prints: "Size=3"

  PRINT_SIZE( string("ABCDEF",3) ); // OK, prints: "Size=3"
  PRINT_SIZE( string{"ABCDEF",3} ); // OK, prints: "Size=3"

  return 0;
}


The list is split into several macro parameters. When you write

PRINT_SIZE( string{"ABCDEF",3} );

This attempts to expand the macro PRINT_SIZE with two parameters, one string{"ABCDEF" and one 3}, which fails. This can be worked around in many cases (including yours) by adding another pair of parentheses:

PRINT_SIZE( (string{"ABCDEF",3}) );

These parentheses prevent the splitting of the argument, so that PRINT_SIZE is expanded with a single argument (string{"ABCDEF",3}) (note that the parentheses are part of the argument).

Tags c++11

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK