C中sizeof的内部机制?
Internal mechanism of sizeof in C?
我在 C 中使用 sizeof 获取结构体的大小,但得到的结果出乎意料。
struct sdshdr {
int len;
int free;
char buf[];
};
int main(){
printf("struct len:%d\n",(sizeof(struct sdshdr)));
return 0;
} //struct len:8, with or without buf
我的问题是为什么 buf
不占用任何 space 以及为什么 int
类型的大小在 64 位 CPU 上仍然是 4?
这是 gcc -v
的输出:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix
作为 GNU c 扩展,你有零长度数组:
As a GNU extension, the number of elements can be as small as zero. Zero-length arrays are useful as the last element of a structure which is really a header for a variable-length object:
例如,考虑来自 The gnu c manual
的这段代码
struct line
{
int length;
char contents[0];
};
{
struct line *this_line = (struct line *)
malloc (sizeof (struct line) + this_length);
this_line -> length = this_length;
}
In ISO C99, you would use a flexible array member, which is slightly different in syntax and semantics:
Flexible array members are written as contents[] without the 0.
Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero.
Flexible array members may only appear as the last member of a struct that is otherwise non-empty.
A structure containing a flexible array member, or a union containing such a structure (possibly recursively), may not be a member of a structure or an element of an array. (However, these uses are permitted by GCC as extensions.)
[] 是一个灵活数组成员。它们不计入结构的总大小,因为 C 标准明确这样说:
6.7.2.1/18
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. In most situations,
the flexible array member is ignored. In particular, the size of the structure is as if the
flexible array member were omitted except that it may have more trailing padding than
the omission would imply.
这是故意设计的,因为灵活的数组成员的目的是允许您在结构之后动态分配尾随数据。 (当结构是文件头、协议头等时)
Example 包括关于非标准 gcc 扩展和旧的 C99 之前的讨论 "struct hack"。
从 C99 开始,结构末尾的数组大小可以省略。出于 sizeof(struct)
的目的,此数组的大小似乎为零(尽管它的存在可能会向结构添加一些填充),但其目的是使其长度 灵活 ,即,当为结构分配 space 时,必须在末尾为数组分配所需数量的额外 space。 (为避免越界,数组的实际分配长度应存储在某处。)
在 C99 之前,在结构的末尾有一个大小为 1(或在编译器允许的情况下为 0)的数组然后为其分配更多 space 是一种相当常见的黑客攻击,因此 C99 使通过引入未给出大小的 flexible array member 明确允许这种做法。
buf
这里是 flexible array member
灵活数组成员的类型不完整,因此可能无法应用 sizeof 运算符,而 zero-length arrays
、sizeof evaluates to zero
.
的原始实现
我在 C 中使用 sizeof 获取结构体的大小,但得到的结果出乎意料。
struct sdshdr {
int len;
int free;
char buf[];
};
int main(){
printf("struct len:%d\n",(sizeof(struct sdshdr)));
return 0;
} //struct len:8, with or without buf
我的问题是为什么 buf
不占用任何 space 以及为什么 int
类型的大小在 64 位 CPU 上仍然是 4?
这是 gcc -v
的输出:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix
作为 GNU c 扩展,你有零长度数组:
As a GNU extension, the number of elements can be as small as zero. Zero-length arrays are useful as the last element of a structure which is really a header for a variable-length object:
例如,考虑来自 The gnu c manual
的这段代码 struct line
{
int length;
char contents[0];
};
{
struct line *this_line = (struct line *)
malloc (sizeof (struct line) + this_length);
this_line -> length = this_length;
}
In ISO C99, you would use a flexible array member, which is slightly different in syntax and semantics:
Flexible array members are written as contents[] without the 0.
Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero.
Flexible array members may only appear as the last member of a struct that is otherwise non-empty.
A structure containing a flexible array member, or a union containing such a structure (possibly recursively), may not be a member of a structure or an element of an array. (However, these uses are permitted by GCC as extensions.)
[] 是一个灵活数组成员。它们不计入结构的总大小,因为 C 标准明确这样说:
6.7.2.1/18
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. In most situations, the flexible array member is ignored. In particular, the size of the structure is as if the flexible array member were omitted except that it may have more trailing padding than the omission would imply.
这是故意设计的,因为灵活的数组成员的目的是允许您在结构之后动态分配尾随数据。 (当结构是文件头、协议头等时)
Example 包括关于非标准 gcc 扩展和旧的 C99 之前的讨论 "struct hack"。
从 C99 开始,结构末尾的数组大小可以省略。出于 sizeof(struct)
的目的,此数组的大小似乎为零(尽管它的存在可能会向结构添加一些填充),但其目的是使其长度 灵活 ,即,当为结构分配 space 时,必须在末尾为数组分配所需数量的额外 space。 (为避免越界,数组的实际分配长度应存储在某处。)
在 C99 之前,在结构的末尾有一个大小为 1(或在编译器允许的情况下为 0)的数组然后为其分配更多 space 是一种相当常见的黑客攻击,因此 C99 使通过引入未给出大小的 flexible array member 明确允许这种做法。
buf
这里是 flexible array member
灵活数组成员的类型不完整,因此可能无法应用 sizeof 运算符,而 zero-length arrays
、sizeof evaluates to zero
.