【发布时间】:2021-01-30 20:23:45
【问题描述】:
以下哪些 C++ lambdas/语句应该根据最新的 C++ 规范工作?
相关情况下的上下文:see here。
我在使用 clang 11.0.0 和 gcc 10.2.1 的 Fedora 33 上使用-std=c++17 测试了以下代码 sn-ps。
更新: 将 __PRETTY_FUNCTION__ 替换为 __func__ 以符合标准。可以观察到相同的行为。
更新 2: Example 使用 const char * s = __func__ 作为默认参数来验证它在函数范围内是否有效(感谢 @BenVoigt)。
1。 LLVM __func__ 在 lambda 默认参数中
void clang() {
[](const char* c = __func__) {std::cout << c << std::endl;}();
}
预期行为(CLANG):
- 打印出
clang\n(void clang()for__PRETTY_FUNCTION__)
观察到的行为(CLANG):
- 编译器警告:
warning: predefined identifier is only valid inside function [-Wpredefined-identifier-outside-function] - 打印出
\n(top level()for__PRETTY_FUNCTION__)
2。 GCC 忽略语句
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
}
预期输出 (GCC):
gcc1
gcc
gcc1
gcc2
观察到的输出 (GCC):
gcc
gcc2
3。 GCC编译错误
void gcc3() {
std::string_view s = [](const char* c = __func__) { return std::string_view(c); }();
std::cout << s << std::endl;
}
预期行为 (GCC): 编译没有问题。
观察到的行为 (GCC): error: internal compiler error: in finish_expr_stmt
【问题讨论】:
-
@Enrico:“改为定义函数”是什么意思? “本地函数”的 g++ 扩展?本地定义的类类型的成员函数?
-
我指的是使用函数而不是 lambda 函数对象。但我没有理解问题的重点,即这些
__variables__的行为方式,lambdas 也只是一个调节这些变量所指内容的工具。 (可能我仍然误解了这个问题。)
标签: c++ gcc lambda clang c++17