1

I have defined the following pre-processor directive:

#define TIMER(name) ::my_app::Timer timer##__LINE__(name)

Using as follows:

TIMER("first");
TIMER("second");

I get an error stating that the second usage redefines timer__LINE__.

::my_app::Timer timer__LINE__("first");
::my_app::Timer timer__LINE__("second");

What I actually want is a definition of timer with the source code line number appened, e.g.:

::my_app::Timer timer1("first");
::my_app::Timer timer2("second");

If it's any use, my clang version details:

❯ /Library/Developer/CommandLineTools/usr/bin/clang --version
Apple clang version 11.0.3 (clang-1103.0.32.29)
Target: x86_64-apple-darwin19.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

I see examples of where this syntax is used and works (::Hazel::InstrumentationTimer timer##__LINE__(fixedName.Data)). Why is the token pasting operator not working as I'd expect in my scenario?

junglie85
  • 1,243
  • 10
  • 30
  • Does it really work there? – bipll Jul 24 '20 at 10:52
  • I assume so - there are a reasonable number of contributors and I suspect significantly more using it (it's from a YouTube series). But the original is MSVC, so perhaps compiler implementation differences cause it to work there? – junglie85 Jul 24 '20 at 13:26
  • Thanks for the linked question - solved perfectly. – junglie85 Jul 24 '20 at 13:27

1 Answers1

0

You need to defer the concatenation after the evaluation of __LINE__:

#define CONCAT(a,b) a b
#define PASTE(a,b) a##b
#define TIMER(name) ::my_app::Timer CONCAT(PASTE,(timer,__LINE__)) (name)

Alternatively, name the variable like the timer name using the stringify-operator:

#define TIMER(name) ::my_app::Timer timer##name (#name)

TIMER(first)
TIMER(second)

results in

::my_app::Timer timerfirst ("first")
::my_app::Timer timersecond ("second")
Erlkoenig
  • 2,664
  • 1
  • 9
  • 18