正在将压缩结构成员的引用传递给模板.gcc错误
Passing reference of packed struct member to template. gcc bug?
我遇到一个问题,将结构成员传递给模板函数。函数的目标是获取成员的地址和大小。这里有一个简单的例子:
这就是结构。它具有压缩属性。
struct TestStruct {
unsigned char elem1;
unsigned char elem2;
uint64_t elem3;
char buf[10000];
int elem4;
unsigned char elem5;
}
__attribute__ ((packed));
这是模板函数,它应该获得成员的地址
template<typename T>
void addData(const T &val)
{
printf ("address inside func: %p n",&val);
}
int main(int argc, char *argv[])
{
TestStruct testdata;
testdata.elem4 = 0;
printf ("struct address is: %p n",&testdata);
printf ("elem4 address is: %p n",&testdata.elem4);
addData(testdata.elem4);
return 0;
}
问题:当属性((packed));已设置(如示例中所示)模板函数接收到错误的成员地址:
输出:
struct address is: 0x7fff735bb4e0
elem4 address is: 0x7fff735bdbfa
address inside func: 0x7fff735bb4dc
如果我去掉"packed"属性,一切都可以。没有错误,也没有警告(即使使用-Wall-Wextra),但没有将正确的地址传递给函数。
我读到这个:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566
并发现存在获取对压缩结构成员的引用的问题。有趣的是,替换常量T&与T&在我的模板函数中,生成错误消息:
error: cannot bind packed field ‘testdata.TestStruct::elem4’ to ‘int&’
所以,我有两个问题:
为什么打包的结构成员不能作为常量引用传递,而它们的地址可以作为指针传递
常数T&案例没有错误,也没有警告,但是错误的地址被传递给了函数。正如我们所知,引用的地址是变量的地址,引用指向.
您的两个问题都在您发布的链接中得到了回答。
1.为什么压缩结构成员不能作为常量引用传递,而它们的地址可以作为指针传递
Gabriel M.Beddingfield在评论中写道:
对象的所有赋值都是short&和short*是不正确的,理想情况下它们都会导致编译器错误。
C++规范(C++03,第3.9、3.9.1、3.9.2节)非常清楚;指向T"的指针;具有实施特定的对齐要求。如果你有一个";指向T"的指针;那么您可能会认为它符合对齐要求。我相信C规范也有类似的语言。
我只能添加C++14标准的相应报价([basic.align]/1):
对象类型具有对齐要求(3.9.1,3.9.2),该要求对可以分配该类型对象的地址进行了限制。对齐是一个实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数。对象类型将对齐要求强加给该类型的每个对象;可以使用对齐说明符请求更严格的对齐
它的底线是,即使获取压缩结构成员的地址也应该是错误的。
2.常量T&案例没有错误,也没有警告,但是错误的地址被传递给了函数。正如我们所知,引用的地址是变量的地址,引用指向。
Jonathan Wakely写道:
const引用导致创建临时的,您没有绑定到压缩字段
最重要的是,不能将非常量引用绑定到压缩结构字段本身并不是一个错误,一个错误是同时可以获取它的地址。编译器应该允许或不允许两者。
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 初始化迭代器错误 C++ 在 GCC 编译器中
- GCC:随机构建导致执行期间分段错误
- 错误:使用 clang 没有可行的重载,使用 GCC 编译
- "未定义对'WinMain@16'的引用"gcc 编辑器中的错误
- 与NVIDIA链接的错误GCC版本
- std::seed_seq编译错误(GCC错误?)
- 使用 lambda 的错误 gcc 行为
- std :: sort函数上的编译器错误(GCC 4.4)
- C++ 编译错误(gcc 4.7)
- 套接字错误 gcc 无法在 WinSock2.h 中获取函数
- Linux编译错误-GCC 4.3.4-模板参数列表太少
- 如何解决在Zero C Ice编译中的upCast错误?- Gcc - 4.7使用clang编译
- GCC 6.1.0 分段错误 - GCC 错误
- std::bind 编译器错误 gcc
- VS2013过载错误(GCC不会发生)
- 使用Python.h编译错误gcc