Reputation: 3012
I'm trying to create a macro so I can specify that a function is not implemented yet (and will crash the program when invoked). Here's what I came up with:
#define NIMPL crash(__PRETTY_FUNCTION__ " not implemented yet")
And you'd use it like so:
void myFunction() {
NIMPL;
}
However, this usage causes this error:
../feta/include/feta.h:19:41: error: expected ‘)’ before string constant
#define NIMPL crash(__PRETTY_FUNCTION__ " not implemented yet")
^
crash()
is a function that accepts one string as a parameter, prints out the message, and calls exit(1)
.
I can confirm that __PRETTY_FUNCTION__
alone, without the concatenation works fine. Also, concatenating two strings without __PRETTY_FUNCTION__
works fine: "<stuff>""<other stuff>"
. But doing both at the same time does not work.
I've tried using the stringizing operator, but it did not work (if it even exists in GCC).
Upvotes: 2
Views: 3147
Reputation: 70442
In C (as the question was originally tagged), __PRETTY_FUNCTION__
is another name for __func__
, which is not a string literal. In C++, it is decorated with the function signature, but it is still not a string literal.
From the documentation (especially note the last sentence):
The identifier
__func__
is implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declarationstatic const char __func__[] = "function-name";
appeared, where function-name is the name of the lexically-enclosing function. This name is the unadorned name of the function. As an extension, at file (or, in C++, namespace scope),
__func__
evaluates to the empty string.
...
In C,__PRETTY_FUNCTION__
is yet another name for__func__
, except that at file (or, in C++, namespace scope), it evaluates to the string"top level"
. In addition, in C++,__PRETTY_FUNCTION__
contains the signature of the function as well as its bare name.
...
These identifiers are variables, not preprocessor macros, and may not be used to initializechar
arrays or be concatenated with string literals.
Since you are using C++, you may consider defining crash
as a variadic template function rather than a macro, to provide some more flexibility.
void crash_t (std::ostringstream &oss)
{
oss << std::endl;
write(2, &oss.str()[0], oss.str().size());
exit(1);
}
template <typename A, typename... REST>
void crash_t (std::ostringstream &oss, A arg, REST... rest)
{
oss << arg;
crash_t(oss, rest...);
}
template <typename... ARGS>
void crash (ARGS... args)
{
std::ostringstream oss;
crash_t(oss, args...);
}
Upvotes: 2
Reputation: 263387
Standard C and C++ provide the "magic identifier" __func__
, which acts as if it were the name of a static char
array containing the name of the current function. (Actually the value is implementation-defined in C++.)
gcc, as an extension, provides __PRETTY_FUNCTION__
, which is identical to __func__
for C, and provides some additional information for C++.
That doesn't solve the problem you're asking about, which is that string literal concatenation applies only to string literals.
You say your crash()
function takes a single string as an argument.
I suggest either modifying crash()
so it takes two arguments, or writing a new wrapper function that takes two arguments. You can then use:
#define NIMPL crash(__PRETTY_FUNCTION__, " not implemented yet")
(Since you're using C++ you can overload it with the same name.) Concatenating the two strings is left as an exercise.
You could also add a second string argument to your existing crash()
function and give it a default value of ""
to avoid breaking existing calls.
Upvotes: 3