I'm writing a simple build file with bash, that is suppose to make it easy for me to switch entry point by emulating Python's
if __name__ == '__main__':
main()
My idea was to include a macro by passing -D __MAIN__=\"$MAIN_FILE\"
to clang++, where MAIN_FILE
is a file you specify when running the build script. Then I'll just have to compare the macro __MAIN__
to the predefined standard macro __FILE__
for each source file. Something like this:
#if equals(__FILE__, __MAIN__)
int main()
{
/* code */
return 0;
}
#endif
The problem I'm encountering is making the function equals
to work in compile-time. Reading up on this it seems like it should be possible to define a constexpr function that compares the strings in compile-time (at least according to this and this answer).
However, whenever I try to create such a function (or copying the code from here or here), I get the following error:
error: function-like macro 'equals' is not defined
Which seems strange to me since it's neither a macro or undefined. I couldn't find a solution when searching for the error message either.
Here's the full code for reference:
#include <iostream>
constexpr bool equals(const char* a, const char* b)
{
return *a == *b && (*a == '\0' || equals(a + 1, b + 1));
}
#if equals(__FILE__, __MAIN__)
int main()
{
std::cout << "Running " << __MAIN__ << std::endl;
return 0;
}
#endif
Compiled with:
clang++ main.cpp -std=c++14 -D __MAIN__="fullpath/main.cpp"
What's causing this error and how can I solve my problem?
#if
and #endif
are preprocessor directives - the preprocessor runs as part of the compilation step, but it is not aware about C++ as a language.
You cannot mix and match the preprocessor with C++ features such as constexpr
functions.
If you want this to work, you need to implement your own #define EQUALS
macro that checks string equality entirely in the preprocessing step. I'm not sure whether or not it's possible (and worth it).