Which of the following C++ lambdas/statements are supposed to work according to the latest C++ specification?
Context in case this is relevant: see here.
I tested the following code snippets with -std=c++17
on Fedora 33 with clang 11.0.0 and gcc 10.2.1.
Update: Replace __PRETTY_FUNCTION__
with __func__
for standard compliance. The same behavior can be observed.
Update2: Example using const char * s = __func__
as default argument to verify that it should be valid within a function scope (thanks to @BenVoigt).
1. LLVM __func__
within lambda default argument
void clang() {
[](const char* c = __func__) {std::cout << c << std::endl;}();
}
Expected behavior (CLANG):
- Print out
clang\n
(void clang()
for__PRETTY_FUNCTION__
)
Observed behavior (CLANG):
- Compiler warning:
warning: predefined identifier is only valid inside function [-Wpredefined-identifier-outside-function]
- Print out
\n
(top level()
for__PRETTY_FUNCTION__
)
2. GCC ignores statements
template <typename L>
constexpr std::string_view methodName(L l) { return l(); }
#define __METHOD_NAME__ (\
__func__, /* needed for pointer to work */ \
methodName([](const char* c = __func__) {return std::string_view(c);}) \
)
void gcc1() {
std::cout << [](const char* c = __func__) { return c; }() << std::endl; // GCC: This statement doesn't do anything
std::cout << [](const char* c = __func__) { return c; }("gcc") << std::endl;
std::cout << __METHOD_NAME__ << std::endl; // GCC: This statement somehow conflicts with the statements above
}
void gcc2() {
std::cout << __METHOD_NAME__ << std::endl; // GCC: This statement itself works
}
Expected output (GCC):
gcc1
gcc
gcc1
gcc2
Observed output (GCC):
gcc
gcc2
3. GCC Compile error
void gcc3() {
std::string_view s = [](const char* c = __func__) { return std::string_view(c); }();
std::cout << s << std::endl;
}
Expected behavior (GCC): Compiles without problems.
Observed behavior (GCC): error: internal compiler error: in finish_expr_stmt