生活智库网
白蓝主题五 · 清爽阅读
首页  > 亲子教育

编译器警告flexible array member:编程学习中的小插曲

孩子最近迷上了ref="/tag/132/" style="color:#C468A7;font-weight:bold;">编程,每天放学回家第一件事就是打开电脑写代码。前两天他皱着眉头问我:‘爸爸,这个编译警告“flexible array member”到底是什么意思?’我一看,原来是他在用C语言写一个简单的学生信息管理系统时遇到了问题。

什么是flexible array member

他写的结构体长这样:

struct student {
    int id;
    char name[20];
    int scores[];  // 可变长数组成员
};

这个 scores[] 就是所谓的“flexible array member”,中文叫“灵活数组成员”。它是C99标准引入的一个特性,允许结构体最后一个成员是一个未指定大小的数组,用来在运行时动态分配空间。比如你想存不同数量的成绩,就可以根据实际需要来分配内存。

为什么会有警告

其实严格来说,这不一定是错误,而是一种提醒。有些编译器在开启较高警告级别时,会提示你这个特性的使用可能存在移植性问题。特别是如果你的代码将来要在较老的编译器上运行,或者团队里有人用的是C++编译器(它不支持这个语法),就容易出问题。

后来我们一起查资料发现,GCC推荐的写法是把长度设为0,像这样:

struct student {
    int id;
    char name[20];
    int scores[0];
};

虽然C标准规定不能定义长度为0的数组,但GCC作为一个扩展支持这种写法,而且更明确地表达了意图。不过从严格C标准角度看,还是用空括号 [] 更合规。

和孩子一起调试的过程

那天晚上我们一边改代码一边聊,他突然说:‘原来写程序就像搭积木,每一块都得对得上才行。’我说没错,就像你们做数学题,步骤错了结果就不对。他点点头,又继续敲键盘去了。

最后我们用了标准写法,并加上注释说明用途。重新编译后,警告消失,程序也跑通了。他高兴地说:‘下次我看到这个警告就知道怎么处理了!’