当在嵌套的lambda中使用“decltype”时,GCC的分离错误
GCC Segfaults When `decltype` Used in Nested Lambda
我创建了一个宏,可以方便地构建lambda函数,使用它我可以迭代我编写的库中的张量对象。但是,嵌套这些宏似乎会导致 GCC 出现内部分段错误。在扩展编译器的预处理器输出并经过一些试验和错误时,我发现原因似乎是在类或结构的方法中声明的嵌套 lambda 函数的参数列表中使用了decltype
。下面是使用标准库的最小示例。
#include <iostream>
#include <type_traits>
template <class Iterator, class Func>
void for_each(const Iterator first, const Iterator last, Func func)
{
for (Iterator it = first; it != last; ++it) {
func(*it);
}
}
template <class T>
class helper
{
typedef typename T::size_type type;
};
template <class T>
class helper<T&>
{
typedef typename T::size_type type;
};
template <class T>
class helper<T*>
{
typedef typename T::size_type type;
};
struct bar
{
struct foo
{
typedef int size_type;
} foo_;
void test()
{
int arr[] = { 1, 2, 3 };
for_each(arr, arr + 3, [&](int i) {
/*
** XXX: The "typename ... type" segfaults g++!
*/
for_each(arr, arr + 3, [&](typename helper<decltype(foo_)>::type j) {
});
});
}
};
int main()
{
return 0;
}
编译器输出:
$ g++ -Wall -std=c++0x nested_lambda.cpp
nested_lambda.cpp: In lambda function:
nested_lambda.cpp:42:56: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.6/README.Bugs> for instructions.
Preprocessed source stored into /tmp/ccqYohFA.out file, please attach this to your bugreport.
我最初选择使用 decltype
是因为对象被传递给宏,我需要提取对象的类型。从对象的类型(T
、T&
或T*
(,我会使用一个特征类来拉取T::size_type.
size_type
然后是lambda函数参数的类型。
如何在不必使用 typedef 提前声明 lambda 函数参数类型的情况下规避此问题?如果您能想到可以在宏中轻松实现的其他解决方案(即在 lambda 函数的参数列表中重复复制和粘贴(,那也将起作用。
对于那些可能遇到类似问题的人来说,作为一个非常粗略的解决方法,我能想到的最佳标准解决方案是让宏提前声明一个 typedef,连接类似 GUID 的前缀(我个人建议_qki_zbeu26_w92b27bqy_r62zf91j2n_s0a02_
(和__LINE__
为typedef名称生成一些莺莺的废话。幸运的是,这个名字不会与任何其他定义发生冲突。
用于 lambda 函数参数类型,也能连接相同的__LINE__
,需要由最初传递宏参数的宏生成莺莺名称,如下面的代码示例所示。
#define _foo_GUID
_qki_zbeu26_w92b27bqy_r62zf91j2n_s0a02_
#define _foo_MANGLE_IMPL2(a, b)
a ## b
#define _foo_MANGLE_IMPL(a, b)
_foo_MANGLE_IMPL2(a, b)
#define _foo_MANGLE(a)
_foo_MANGLE_IMPL(_foo_GUID, a)
将_foo_MANGLE(__LINE__)
作为宏参数传递时,请确保存在额外的间接寻址级别,以便在使用_foo_MANGLE(__LINE__)
之前对其进行评估。
此错误目前正在解决中,我认为应该很快就会修复。
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 奇怪的结构&GCC&clang(void*返回类型)
- GCC本机矩阵运算库
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- gcc和c++17的过载解析失败
- 数据成员SFINAE的C++17测试:gcc vs clang
- GCC对可能有效的代码抛出init list生存期警告
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 使用gcc从静态链接的文件中查找可选符号
- 普通环路未使用gcc 4.8.5自动矢量化
- 有了gcc,是否可以链接库,但前提是它存在
- 在clang++预处理器中确定gcc工具链版本
- 为什么 gcc 编译这个而 msvc 没有
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- GCC shared_ptr和地图上make_shared分离的变量类型错误
- 当在嵌套的lambda中使用“decltype”时,GCC的分离错误