关于结构体中零长度数组的问题
2009-06-12 22:37
253 查看
在许多代码里都出现了类似的结构体 struct ast_exten { char *exten; /* Extension name */ int matchcid; /* Match caller id ? */ char *cidmatch; /* Caller id to match for this extension */ int priority; /* Priority */ char *label; /* Label */ struct ast_context *parent; /* The context this extension belongs to */ char *app; /* Application to execute */ void *data; /* Data to use (arguments) */ void (*datad)(void *); /* Data destructor */ struct ast_exten *peer; /* Next higher priority with our extension */ const char *registrar; /* Registrar */ struct ast_exten *next; /* Extension with a greater ID */ char stuff[0]; }; 就是零长度的数组 关于这个问题,存在几个需要弄清楚的地方。第一,char p[0]是否合法;其次,如果非法,按照标准,合法的代码是怎样的? 先解释第一点,在ISO/IEC 9899-1999里面,这么写铁定是非法的,这个仅仅是GNU C的扩展,gcc可以允许这一语法现象的存在。考虑以下代码: #include <stdio.h> int main(int argc, char* argv[]) { char ia[0]; printf("%d/n", sizeof(ia)); return 0; } 这个在gcc里面编译,即使你使用了-Wall参数,gcc仍然会让这段代码通过……如果需要强制编译器按照ISO C标准进行编译,你需要给出-pedantic(或者-pedantic_error)参数,这样,编译器会报告:ISO C forbids zero-size array `ia' 这个仅仅是在C99没有出台的情况下,gcc为了使用类似于C99 flexible array member而做出的一个work-around,但是现在C99出现了,并且正式支持了flexible array member的语法,这样的一个GNU C扩展就有点显得不合时宜了……按照ISO/IEC 9899-1999的要求,flexible array member的定义应当是这样: struct foo { int variable; int bar[];//here!!!! }; 这个才是符合标准要求的写法,当你的代码需要跨平台、跨编译器移植,并且需要这个特性的时候,这个才是唯一准确的写法! 本来这里有一个trick,只不过flexible array member将其标准化了而已。 原来的trick应该是写作 struct foo { int variable; int i_am_a_trick[1]; }; struct foo *ptr_to_foo = malloc(sizeof(struct foo) + SOMELENGTH); 因为标准看到了这种trick可能造成的问题: struct foo something[2];//本以可能并不是这样,对于flexible array member来说,这个会被标记为错误或者警告,防止出现问题…… extension flexible array member,是C99允许的。标准原文如下(第117页): As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member. With two exceptions, the flexible array member is ignored. First, the size of the structure shall be equal to the offset of the last element of an otherwise identical structure that replaces the flexible array member with an array of unspecified length.106) Second, when a . (or ->) operator has a left operand that is (a pointer to) a structure with a flexible array member and the right operand names that member, it behaves as if that member were replaced with the longest array (with the same element type) that would not make the structure larger than the object being accessed; the offset of the array shall remain that of the flexible array member, even if this would differ from that of the replacement array. If this array would have no elements, it behaves as if it had one element but the behavior is undefined if any attempt is made to access that element or to generate a pointer one past it. |
相关文章推荐
- 关于数组长度问题你都全都掌握了吗?数组求长度练习题就在这里
- 关于包含0长数组的结构体对齐问题(C语言 Linux_x64 GNU编译器)
- 【C语言】关于结构体最后的长度为0或1数组的思考
- 关于对字符串、数组处理的常见问题与方法,如获取带有空格字符串长度,数组长度等。getline(),sprintf()使用。
- C语言:字符串、结构体中关于数组的几个问题
- 关于结构体数组初始化的问题--深入举例
- 关于结构体的长度问题(字节对齐)
- 关于零长度的数组——结构体最后一个成员char[0]和char[1]
- 关于memcpy拷贝结构体、结构体数组到字符数组(字符串)的问题
- 关于结构体定义时初始化及结合数组使用问题 示例
- 关于结构体里面的字符串指针输出出现乱码的问题与结构体数组作为参数传值的问题
- 关于结构体中的数组问题
- 关于结构体数组的赋值问题
- 关于memcpy拷贝结构体、结构体数组到字符数组(字符串)的问题
- 关于数组做形参,用sizeof测长度的问题
- 发现关于数组求其长度 strlen 和 sizeof的问题
- 关于结构体数组初始化的问题--深入举例
- 关于字符数组的长度问题
- C语言中,关于数组和结构体变量的的默认初值问题
- 编程之美4:那些常被考到的关于数组的最大子数组问题