GCC 6的灵活数组错误,但GCC 4则没有 [英] Flexible array error with gcc 6 but not with gcc 4
问题描述
我正在尝试编译一位同事编写的一段代码.在装有gcc 6.1.1的计算机上,出现此错误:
I'm trying to compile a piece of code written by a colleague. On my machine with gcc 6.1.1 I get this error:
In file included from src/TYAGlobalLibs.cc:1:0:
./include/TYAGlobalLibs.hh:112:17: error: flexible array member ‘TYA::TMultiHist::fh’ not at end of ‘class TYA::TMultiHist’
TH1F *fh[];
^
./include/TYAGlobalLibs.hh:102:9: note: in the definition of ‘class TYA::TMultiHist’
class TMultiHist{
^~~~~~~~~~
这似乎是一条禁止的代码路径,因此会触发编译器错误;但是,使用gcc 4.5.2可以编译同一文件而不会出现错误.我将这些编译器选项用于g ++:
It seems that this is a forbidden code path and as such it triggers a compiler error; however, using gcc 4.5.2 the same file compiles without error. I use these compiler options for g++:
-O2 -Wall -fPIC -pthread -m32 -std=c++98
对于6.1.1和4.5.2.万一重要,gcc 6可以在64位计算机上运行,而gcc 4可以在32位计算机上运行.这是重现此问题的最小代码段:
for both 6.1.1 and for 4.5.2. In case it matters, gcc 6 runs on a 64 bit machine while gcc 4 on a 32 bit one. Here's a minimal code snippet to reproduce the issue:
struct test{
int a;
float b[];
double c;
};
int main(){
}
有人知道为什么会发生这种情况吗?最终,如果有编译器选项可以使gcc 6进行编译而不会出现错误(我没有机会更改代码,这不在我的控制之下)?
Does anybody know why this happens and eventually if there are compiler options to make gcc 6 compile without errors (I have no chance of changing the code, it's not under my control)?
推荐答案
在C(C99和更高版本)中,可以使用 []
定义 flexible数组成员,并且必须是结构的最后一个成员.C ++不支持灵活的数组成员,但是g ++允许它们作为语言扩展.
In C (C99 and later), a flexible array member can be defined with []
, and must be the last member of a structure. C++ doesn't support flexible array members, but g++ permits them as a language extension.
较早版本的g ++不需要灵活的数组成员即可成为类或结构的最后一个成员.这是一个错误,已在较新版本的g ++中更正.
Older versions of g++ do not require a flexible array member to be the last member of a class or struct. This is a bug, which has been corrected in newer versions of g++.
这是一个基于您的小型测试程序,可以说明问题:
Here's a small test program, based on yours that illustrates the problem:
#include <iostream>
#include <cstddef>
static int mem[100];
struct test{
int a;
int b[];
int c;
};
int main(){
test *ptr = (test*)&mem;
ptr->a = 10;
ptr->b[0] = 20;
ptr->b[1] = 30;
ptr->c = 40;
std::cout << "ptr->a = " << ptr->a << "\n";
std::cout << "ptr->b[0] = " << ptr->b[0] << "\n";
std::cout << "ptr->b[1] = " << ptr->b[1] << "\n";
std::cout << "ptr->c = " << ptr->c << "\n";
}
这是我用g ++ 4.1.2编译时的输出:
And here's the output when I compile it with g++ 4.1.2:
ptr->a = 10
ptr->b[0] = 40
ptr->b[1] = 30
ptr->c = 40
如您所见,成员 c
被分配为与 b [0]
相同的偏移量.
As you can see, the member c
is allocated at the same offset as b[0]
.
(严格来说,由于可能的对齐问题,使用 int []
数组保存 test
对象不是100%安全,但这不太可能是问题.)
(Strictly speaking, using an int[]
array to hold a test
object isn't 100% safe due to possible alignment problems, but that's unlikely to be an issue in practice.)
因此,您的代码很可能有未发现的错误.
It's very likely that your code has undiscovered bugs because of this.
您的问题不是更新的g ++拒绝了您的代码;而是是年长的人没有.
Your problem is not that the newer g++ rejects your code; it's that the older one doesn't.
对成员声明进行重新排序以使灵活数组成员最后出现是最简单的解决方法-尽管您(或其他人)将需要仔细检查类型的使用方式.更好的解决方案可能是用某些C ++容器类(例如, std :: vector
.
Reordering the member declarations so the flexible array member appears last is the simplest fix -- though you (or someone else) will need to carefully examine how the type is used. A far better solution is probably to replace the flexible array member with some C++ container class, perhaps a std::vector
.
(我没有机会更改代码,不受我的控制)
(I have no chance of changing the code, it's not under my control)
某人可以更改代码,并且大概您可以提交错误报告.
Somebody is able to change the code, and presumably you're able to submit a bug report.
这篇关于GCC 6的灵活数组错误,但GCC 4则没有的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!