#include <iostream>
using namespace std;
const string getFileNameAsVarName(string filename, int lineNo)
{
string s = "";
for (char c : filename)
{
if (c > 'a' && c < 'z')
{
s += c;
}
}
return s + to_string(lineNo);
}
#define DYNAMIC_NAME() (getFileNameAsVarName(__FILE__, __LINE__))
#define NAME() aaa
int main()
{
int NAME() = 123; // OK Expands to: aaa
int DYNAMIC_NAME() = 234; //Not OK Expands to:
// (getFileNameAsVarName("/Users/guichizhao/Documents/GitHub/learn/main.cpp", 29))
return 0;
}
It may look wired, but we have a valid use case. Our intention is to declare a dynamically named variable i.e. The variable name is determined by the filename and lineNo, We try to achieve this by using a macro, it seems the only chance we get to achieve our goal. The problem is that a file name is not a legal cpp variable name, If we make it legal using cpp code, the MACRO complains, after the MACRO substitution, it is not valid anymore, see the comment in the code
So, is there any way to solve the dilemma, or is there another way to get a dynamically named variable?
In addition, we use CMake in our project, not sure if CMAKE can help, any solutions related to CMAKE are also highly appreciated
You can't, fundamentally.
Macros are handled by the C++ preprocessor. It works on tokens. It can turn a token into a string (FOO => "FOO") but it can't turn a string back into a token. __FILE__
is a string, as you discovered, while a variable name has to be an unquoted token.
getFileNameAsVarName
is a C++ function, and even consteval
functions run after the preprocessor has completely finished. At that time, all tokens are final.