在Linux内核代码中,我发现了以下无法理解的内容.
struct bts_action {
u16 type;
u16 size;
u8 data[0];
} __attribute__ ((packed));
Run Code Online (Sandbox Code Playgroud)
代码在这里:http://lxr.free-electrons.com/source/include/linux/ti_wilink_st.h
零元素数据数组的需求和目的是什么?
考虑:
struct box
{
int array[3];
};
int main()
{
box a = {1};
}
Run Code Online (Sandbox Code Playgroud)
如果以上工作在C++中那么为什么以下工作不起作用?
struct box
{
int simple_int;
};
int main()
{
box b = 2;
}
Run Code Online (Sandbox Code Playgroud)
是什么原因?
我正在重构一些旧的代码,并发现很少的结构包含零长度数组(如下).当然,由pragma压制的警告,但我没有通过包含这种结构的"新"结构创建(错误2233).数组'byData'用作指针,但为什么不使用指针呢?或长度为1的数组?当然,没有添加任何评论让我喜欢这个过程...任何使用这种东西的原因?重构那些的任何建议?
struct someData
{
int nData;
BYTE byData[0];
}
Run Code Online (Sandbox Code Playgroud)
NB它是C++,Windows XP,VS 2003
我使用sizeof来获取C中结构的大小,但我得到的结果是意外的.
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
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么不buf占用任何空间,为什么int64位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
Run Code Online (Sandbox Code Playgroud) 我有两个结构定义如下:
struct EmptyStruct{
};
struct StructEmptyArr{
int arr[0];
};
int main(void){
printf("sizeof(EmptyStruct) = %ld\n", sizeof(EmptyStruct));
printf("sizeof(StructEmptyArr) = %ld\n", sizeof(StructEmptyArr));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在Ubuntu 14.04,x64上用gcc(g ++)4.8.4编译.
输出(对于gcc和g ++):
sizeof(EmptyStruct) = 1
sizeof(StructEmptyArr) = 0
Run Code Online (Sandbox Code Playgroud)
我能理解为什么sizeof(EmptyStruct)等于1但不能理解为什么sizeof(StructEmptyArr)等于0.为什么两者之间存在差异?
假设我想获取大小未知的自动数组的最后一个元素.我知道我可以利用sizeof运算符来获取数组的大小并相应地获取最后一个元素.
使用*((*(&array + 1)) - 1)安全吗?
喜欢:
char array[SOME_SIZE] = { ... };
printf("Last element = %c", *((*(&array + 1)) - 1));
Run Code Online (Sandbox Code Playgroud)
int array[SOME_SIZE] = { ... };
printf("Last element = %d", *((*(&array + 1)) - 1));
Run Code Online (Sandbox Code Playgroud)
等等
我今天接受系统编程课程的教授告诉我们,最后定义一个零长度数组的结构:
struct array{
size_t size;
int data[0];
};
typedef struct array array;
Run Code Online (Sandbox Code Playgroud)
这是一个有用的结构,用于定义或初始化带有变量的数组,即如下所示:
array *array_new(size_t size){
array* a = malloc(sizeof(array) + size * sizeof(int));
if(a){
a->size = size;
}
return a;
}
Run Code Online (Sandbox Code Playgroud)
也就是说,使用malloc(),我们还为大小为零的数组分配内存.这对我来说是全新的,而且看起来很奇怪,因为从我的理解来看,结构不必在连续的位置上有它们的元素.
为什么代码在array_new内存中分配data[0]?那么,为什么要访问它是合法的
array * a = array_new(3);
a->data[1] = 12;
Run Code Online (Sandbox Code Playgroud)
?
从他告诉我们的内容来看,似乎在结构的末尾定义为长度为零的数组确保在结构的最后一个元素之后立即出现,但这看起来很奇怪,因为再次,根据我的理解,结构可能有填充.
我也看到这只是gcc的一个特性,并没有任何标准定义.这是真的?
今天我偶然定义了一个二维数组,其中一维的大小为0,但是我的编译器没有抱怨.我发现以下内容表明这是合法的,至少在gcc的情况下:
但是,我对这个用法有两个问题:
首先,这被认为是良好的编程习惯吗?如果是这样,那么我们何时应该在现实世界中使用它?
其次,我定义的数组是二维的,一维的0大小.这和一维情况一样吗?例如,
int s[0]
int s[0][100]
int s[100][0]
Run Code Online (Sandbox Code Playgroud)
它们在内存和编译器中都是一样的吗?
编辑:回复Greg:我使用的编译器是gcc 4.4.5.我对这个问题的意图不依赖于编译器,但是如果有任何编译器特定的怪癖也会有用:)
提前致谢!
由Stanley B. Lippman撰写的C++ Primer第5版(ISBN 0-321-71411-3/978-0-321-71411-4)提到:
An
[std::]array是一种更安全,更易于使用的内置阵列替代方案.
内置阵列有什么问题?
在 libc++ 中, 的特化std::array<T,0>有一个成员 ( const)char数组,该数组根据T(源) 进行对齐和调整大小。我想知道这个实现的原因是什么,因为这个成员(__elems_)似乎没有在任何地方使用。为了进行比较,libstdc++使用空成员,而Microsoft STL如果不可默认构造则使用空成员T(否则,它会创建单元素数组)。
差异的现场演示:https ://godbolt.org/z/1o167na6z