警告
本文最后更新于 2023-10-20,文中内容可能已过时。
old-style:[0]
我在查看代码的时候,发现有一个 struct
有 长度为0 的数组。
1
2
3
4
5
|
struct data_t
{
size_t size;
int data[0];
};
|
如果打印出上面结构体,发现长度正好为 size_t
,其中的 data
是不占用内存的。
1
2
3
4
5
|
cout << "sizeof(size_t):" << sizeof(size_t) << endl;
cout << "sizeof(data_t):" << sizeof(data_t) << endl;
//sizeof(size_t):8
//sizeof(data_t):8
|
原来,这样做的目的,是为了可以添加不限长度的数组,通过 malloc
分配内存大小,从而实现在代码中灵活分配数据的目的。
1
2
3
4
5
6
7
|
data_t* get_data(size_t size)
{
data_t* d = (data_t*) malloc(sizeof(data_t) + size * sizeof(int));
if (d)
d->size = size;
return d;
}
|
new-style:[]
其实,这是一种比较古老的写法,我们完全可以使用 arr[]
(flexible array member) 来替代
1
2
3
4
5
6
|
struct data_t
{
size_t size;
//In C99 standard this is not neccessary as it supports the arr[] syntax.
int data[];
};
|
完整的测试代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
using namespace std;
struct data_t
{
size_t size;
//This is an old C hack to allow a flexible sized arrays.
int data[0];
//In C99 standard this is not neccessary as it supports the arr[] syntax.
//int data[];
};
data_t* get_data(size_t size)
{
data_t* d = (data_t*) malloc(sizeof(data_t) + size * sizeof(int));
if (d) d->size = size;
return d;
}
int main()
{
cout << "sizeof(size_t):" << sizeof(size_t) << endl;
cout << "sizeof(data_t):" << sizeof(data_t) << endl;
auto x = get_data(10);
for (size_t i = 0; i < x->size; ++i)
x->data[i] = i*i;
for (size_t i = 0; i < x->size; ++i)
cout << "x[" << i << "]:" << x->data[i] << endl;
return 0;
}
|
best-style:[1]
上面的做法有一个问题,如果使用编译器选项 -pedantic
会有报错提示:
1
2
3
4
5
6
7
8
9
|
## 对于 int data[0]
main.cpp:11:14: warning: ISO C++ forbids zero-size array ‘data’ [-Wpedantic]
11 | int data[0];
| ^
## 对于 int data[]
main.cpp:13:9: warning: ISO C++ forbids flexible array member ‘data’ [-Wpedantic]
13 | int data[];
| ^~~~
|
It’s worth pointing out IMO the best way to do the size calculation, which is used in the Raymond Chen article linked above.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
struct data_t
{
size_t size;
int data[1];
};
data_t* get_data(size_t size)
{
// 使用 offsetof 计算出 data[size] 占用的大小
data_t* d = (data_t*) malloc(offsetof(data_t, data[size]));
if (d) d->size = size;
return d;
}
|
完整的测试代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#include <cstddef>
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
using namespace std;
struct data_t
{
size_t size;
int data[1];
};
data_t* get_data(size_t size)
{
data_t* d = (data_t*) malloc(offsetof(data_t, data[size]));
if (d) d->size = size;
return d;
}
int main()
{
cout << "sizeof(size_t):" << sizeof(size_t) << endl;
cout << "sizeof(data_t):" << sizeof(data_t) << endl;
auto x = get_data(20);
for (size_t i = 0; i < x->size; ++i)
x->data[i] = i*i;
cout << "x.size:" << x->size << endl;
for (size_t i = 0; i < x->size; ++i)
cout << "x[" << i << "]:" << x->data[i] << endl;
return 0;
}
|
Ref: