0

I am trying to get the macro to print out the file name followed by the line number and then the print message, here is how I do this normally, and it works but it prints out the entire file path to the file:

#define TESTER1(...) printf(ANSI_COLOR_BOLD_GREEN "LOG::" __FILE__ ":" STR(__LINE__) "\t" ANSI_COLOR_RESET ANSI_COLOR_GREEN __VA_ARGS__); printf(ANSI_COLOR_RESET "\n")

this works, but the file path is way too long: Example output:

C:\Users\Work\Documents\CastEngine\CastDriver\src\main.cpp:18: Example

What I want the output to be is the following:

main.cpp:18: Example

So here is the macro for that:

#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#define TESTER2(...) printf(ANSI_COLOR_BOLD_GREEN "LOG::" __FILENAME__ ":" STR(__LINE__) "\t" ANSI_COLOR_RESET ANSI_COLOR_GREEN __VA_ARGS__); printf(ANSI_COLOR_RESET "\n")

I know that __FILENAME__ works as intended because without defining TESTER2, I use this code:

printf("%s:%d", __FILENAME__, __LINE__);

and the output is exactly what I want: main.cpp:19

But when I add the TESTER2 define from above, it gives me the following error:

error: expression cannot be used as a function
 #define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
                                                                                       ^
C:\Users\Work\Documents\CastEngine\CastDriver\src\main.cpp:11:59: note: in expansion of macro '__FILENAME__'
 #define TESTER2(...) printf(ANSI_COLOR_BOLD_GREEN "LOG::" __FILENAME__ ":" STR(__LINE__) "\t" ANSI_COLOR_RESET ANSI_COLOR_GREEN __VA_ARGS__); printf(ANSI_COLOR_RESET "\n")
                                                           ^~~~~~~~~~~~
C:\Users\Work\Documents\CastEngine\CastDriver\src\main.cpp:20:5: note: in expansion of macro 'TESTER2'
     TESTER2("Hello\n");

I really have no idea how to fix this; any help would be greatly appreciated.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Yea okay
  • 135
  • 8
  • 2
    String concatenation only works for string literals (`__FILE__` expands into a literal), you can't concatenate strings with expressions. – Barmar Jun 04 '21 at 15:30
  • 2
    You are not allowed to create name with double underscores. Those names are reserved for your implementation. – NathanOliver Jun 04 '21 at 15:30
  • @Barmar, is there a way to turn its output into a literal while maintaining the one liner macro? – Yea okay Jun 04 '21 at 15:32
  • 1
    Of course not. Literals exist at compile time, functions are called at run time. – Barmar Jun 04 '21 at 15:33
  • @Barmar so is there no way to accomplish this? – Yea okay Jun 04 '21 at 15:34
  • Note that you should not, in general, create function, variable, tag or macro names that start with an underscore. Part of [C11 §7.1.3 Reserved identifiers](https://port70.net/~nsz/c/c11/n1570.html#7.1.3) says: — _All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use._ — _All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces._ See also [What does double underscore (`__const`) mean in C?](https://stackoverflow.com/q/1449181) – Jonathan Leffler Jun 04 '21 at 15:45

2 Answers2

1

You can have more than one consecutive string literals and compiler will see them as one.

Example:

printf("He" "llo" "wo" "rld.");

But in your macro __FILENAME__ expands to the strrchr call + ternary operation and the result of it is not the string literal - thus syntax error.

#define TESTER2(...) printf(ANSI_COLOR_BOLD_GREEN "LOG::%s" ":" STR(__LINE__) "\t" ANSI_COLOR_RESET ANSI_COLOR_GREEN __VA_ARGS__, __FILENAME__); printf(ANSI_COLOR_RESET "\n")
0___________
  • 60,014
  • 4
  • 34
  • 74
-1

You could always just use a function to clean it up.

printf("%s:%d",
       absl::StripPrefix(__FILENAME__, "C:\Users\Work\Documents\CastEngine\CastDriver\"),
       __LINE__);
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173