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).
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.
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 declaration
static 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 initialize char 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...);
}
Related
There are many cases where template functions and types need a static-assertion to restrict the acceptable types of specializations or other conditions. Then a meaningful compiler error message is desired. If you don't want to write a string literal one one-by-one for each case, you create some macros for the error messages or for the complete assertions, but
how to implicitly include the name of the type / function to the error message?
In the following example FUNCNAME is a fictional keyword which should make the magic happen:
#include <type_traits>
#define ASSERT_INTEGRAL(T) static_assert(std::is_integral<T>::value, \
FUNCNAME ## " would be happy with specializations for integral types");
template <typename T>
class A
{
public:
A()
{
ASSERT_INTEGRAL(T)
}
};
For template types, if you perform the static assertion inside the constructor, maybe the name of the function just enough. For such cases there is the C99 standard macro __func__, but as it turns out static_assert doesn't accept it as a string literal.
So what is the solution?
As it appears, C++ preprocessor fails if a template instantiation with multiple arguments passed to a macro as an argument.
See an example below.
#include <stdio.h>
#define FOO(v) printf("%d\n",v::val())
template<int N>
struct bar {
static int val() { return N; }
};
template<int N, int M>
struct baz {
static int val() { return N+M; }
};
int main() {
printf("%d\n",bar<1>::val());
printf("%d\n",baz<1,2>::val());
FOO(bar<10>); // OK
FOO(baz<20,30>); // error: too many arguments provided to function-like macro invocation
FOO((baz<20,30>)); // error: '::val' has not been declared
}
Tested with clang++ and g++
Should it be considered as a bug?
No, it's not a bug.
The c preprocessor is a different beast from the rest of the language and it plays by its own rules. Changing this would break compatibility in a massive way, CPP is highly rigorously standardized.
The usual way to work around these comma issues is,
typedef baz<20,30> baz2030_type;
FOO(baz2030_type);
The C/C++ preprocessor recognizes commas as macro argument separators unless they are nested inside parentheses. Just parentheses. Brackets, braces and template markers don't count:
The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments. (C++14 §16.3/11; C11 §6.10.3/11)
(A side effect of the above is that you can use unbalanced braces and brackets as macro arguments. That's usually not a very good idea, but you can do it if you have to.)
Problems occasionally crop up as a result; a common one is unwanted multiple arguments when the argument is supposed to be a block of code:
MY_FANCY_MACRO(1000, { int i=0, j=42; ... })
Here, the macro is called with (at least) 3 arguments, although it was probably written to accept 2.
With modern C++ (and C) compilers, you have a few options. In a fairly subjective order:
Rewrite the macro as an inline function. If the argument is a code block, consider using a templated function which could accept a lambda or other functor. If the argument is a type, make it a template argument instead.
If surrounding the argument with redundant parentheses is syntactically valid, do that. But in such a case it is almost certainly the case that suggestion (1) above would have worked.
Define:
#define COMMA ,
and use it where necessary:
FOO(baz<20 COMMA 30>);
This doesn't require modifying the macro definition in any way, but it will fail if the macro passes the argument to another macro. (The replacement will be done before the inner macro call is parsed, so the multiple argument problem will just be deferred to the inner call.)
If you expect that one macro argument might contain unprotected commas, and it is the last or only argument, and you're in a position to modify the macro, and you're using C++11/C99 or better (or gcc, which has allowed this as an extension for some time), make the macro variadic:
#define FOO(...) printf("%d\n",__VA_ARGS__::val())
The macro's argument is treated as plain text string and the arguments are separated using commas. Hence the comma in the template will be treated as a delimiter. Thus the preprocessor will think that you have passed on two arguments to a single argument macro, hence the error.
BOOST_IDENTITY_TYPE is the solution for that: https://www.boost.org/doc/libs/1_73_0/libs/utility/identity_type/doc/html/index.html
You can also wrap the type into decltype: decltype(std::pair<int, int>()) var; which also adds an extra parentheses, but this unfortunately does an extra ctor call.
Is there a macro to return (ideally as a const char* or indeed cont char *const) the typename of its parameter or some information on it?
This is at compile time, not runtime, so C++'s typeinfo will not do. I run with -fno-rtti anyway.
There isn't.
C++11 does have the __func__ identifier inside function definitions, which produces a string variable with the function name. Most C++ compilers have variations on this to have "decorated" function names.
Instead of writing
cout<<mysteryMacro(std::string<wchar>);
you could write
cout<<"std::string<wchar>";
The only purpose I see is to get typeinformation inside a template, e.g.:
template<T>
void printT() {
cout << "T is of type"<<mysteryMacro(T);
}
Since otherwise you automatically know the code.
This could be achieved with template specialization.
Disclaimer: this was untested, and is just a hint for what SHOULD work. I dont consider this a good solution. I am sure you can convert this to rather return strings than to print. A little more input on what you need this for would be great.
template<T>
void printT() {
code that generates compile error, so you see that you have an undefined type
}
template<>
void printT<string>() {
cout << "you have a <string>";
}
If you would like to use the template for variables you would hav to rely on automatic template parameter deduction like so:
template<>
void printT<string>(T) {
cout << "you have a <string>";
}
and use it like this
int x;
printT(x);
eventhough I do not know why, since, as stated unless you are in a template you will know the type while writing the code and in templates the type is conveyed in the template parameters and thus knwon (not as string) and you could always write printT<T>()
Is it legal to invoke a variadic macro M with no arguments for its variadic parameter?
The relevant standard quote is [cpp.replace]/4:
If the identifier-list in the macro definition does not end with an ellipsis, the number of arguments (including those arguments consisting of no preprocessing tokens) in an invocation of a function-like macro shall equal the number of parameters in the macro definition. Otherwise, there shall be more arguments in the invocation than there are parameters in the macro definition (excluding the ...). There shall exist a ) preprocessing token that terminates the invocation.
For the case with no non-variadic parameters, an invocation in the form M() should be legal as the invocation has one argument (consisting of no preprocessing tokens). So there is one more argument than non-variadic parameters.
For the case with one non-variadic parameter, should there be a trailing , as in M(1,) to introduce an argument consisting of no preprocessing tokens for the variadic parameter? Otherwise, the number of arguments would be equal to the number of non-variadic parameters. i.e.,
#define variadic(x,...) #__VA_ARGS__
variadic(1,) // 2 arguments: ok
variadic(1) // 1 argument: wrong?
Both Clang and GCC, however, accept the following test case:
#include <iostream>
#define variadic(x,...) #__VA_ARGS__
int main()
{
std::cout << "'" variadic(1) "'" << std::endl;
}
and produce as output:
''
Is this non-standard behavior?
Otherwise, there shall be more arguments in the invocation than there are parameters in the macro definition (excluding the ...).
This very extract from the standard shows that your code should not be valid: you have one parameter plus the ellipsis. If we follow the portion of the standard above, you should have at least two arguments. When you write varidadic(1), you just provide one argument. Your code is not valid.
By the way, clang produces a warning:
main.cpp:7:32: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu]
std::cout << "'" variadic(1) "'" << std::endl;
And GCC also produces a warning:
main.cpp:7:32: warning: ISO C99 requires rest arguments to be used [enabled by default]
std::cout << "'" variadic(1) "'" << std::endl;
Since that may be a bother to the programmer, and since the programmer's intent is easy to guess, they both consider variadic(1) is equivalent to variadic(1,).
I recently came across code that looked like this:
void function(int a, int b, int c){
//...
}
int main(){
//...
(function)(1,2,3);
//...
}
What is the point of wrapping the function name separately in parens?
Does it have any affect that would be different than function(1,2,3);?
Why does the language allow such syntax?
The only case I can think of where it would matter is when function is defined as a macro.
In C, standard library functions may also be implemented as function-like macros (for efficiency). Enclosing the function name in parentheses calls the actual function (since the function name is not followed by a ().
As for why the language allows the syntax, a function call consists of an expression of pointer-to-function type followed by the arguments in parentheses. In most cases, the prefix is a function name (which is implicitly converted to a pointer to the function), but it can be an arbitrary expression. Any expression may be enclosed in parentheses, usually without changing its meaning (other than affecting precedence). (But see Jonathan Leffler's comments for some counterexamples.)
In addition to suppressing function-like macro expansions, wrapping an unqualified function name in parentheses suppresses argument-dependent lookup. For example:
namespace meow {
struct kitty {};
void purr(kitty) {}
}
int main() {
meow::kitty stl;
purr(stl); // OK, ADL finds meow::purr
(purr)(stl); // error; no ADL is performed
}