mar*_*nev 3 c99 extern variable-declaration
我有一个数组,其大小在源文件中定义的编译时确定。
const int array[] = {1, 3, 3, 7};
Run Code Online (Sandbox Code Playgroud)
元素的数量将来可能会发生变化,因此我宁愿不在括号中对其进行硬编码。
这个数组需要从几个源文件中访问,所以我试图在头文件中添加一个 extern 声明。但是,由于隐式数组大小,我不确定这是否可行。我尝试了两种变体:
extern const int array[]; // Warning: size of symbol `array' changed from 8 to 16
extern const int *array; // error: conflicting types for 'array'
Run Code Online (Sandbox Code Playgroud)
是否可以这样做,或者我应该寻找解决方法?
在声明变量的标头中,写入:
extern const int array[];
Run Code Online (Sandbox Code Playgroud)
不过,您是对的,其他文件不知道数组的大小。那比较棘手。您可能会在标题中使用:
extern const int array[];
extern const size_t array_size;
Run Code Online (Sandbox Code Playgroud)
以及定义数组的位置:
const int array[] = {1, 3, 3, 7};
const size_t array_size = sizeof(array) / sizeof(array[0]);
Run Code Online (Sandbox Code Playgroud)
您将在定义数组的位置包含标头,以确保交叉引用正确无误。如果您选择使用int而不是size_t(但如果您将编译器设置得足够挑剔,它可能对这个主题有不同的看法),您将不会收到我的抱怨。
请注意,数组大小不是标准意义上的“整数常量”;例如,它不能用于case标签。如果您使用 声明另一个数组array_size,它将是一个 VLA — 可变长度数组。此类数组不能在文件范围(或static函数内的存储类)声明。
答案的 MCVE(最小、完整、可验证示例):
ext-def.h
#include <stddef.h>
extern const int array[];
extern const size_t array_size;
Run Code Online (Sandbox Code Playgroud)
ext-def.c
#include "ext-def.h"
const int array[] = {1, 3, 3, 7};
const size_t array_size = sizeof(array) / sizeof(array[0]);
Run Code Online (Sandbox Code Playgroud)
ext-use.c
#include "ext-def.h"
#include <stdio.h>
int main(void)
{
for (size_t i = 0; i < array_size; i++)
printf("%zu: %d\n", i, array[i]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
汇编
在运行 macOS High Sierra 10.13.2 的 MacBook Pro 上使用 GCC 7.2.0,使用martinkunev在评论中指定的选项:
$ gcc -std=c99 -pthread -O2 -fstrict-aliasing -fomit-frame-pointer -pedantic -o ext-def ext-def.c ext-use.c
$ ./ext-def
0: 1
1: 3
2: 3
3: 7
$
Run Code Online (Sandbox Code Playgroud)
使用我的默认编译选项(C11 不是 C99):
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -c ext-def.c
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -c ext-use.c
$
Run Code Online (Sandbox Code Playgroud)
在任一组选项下同样无警告。您也可以添加-pedantic到 C11 命令行而不会收到任何警告。
| 归档时间: |
|
| 查看次数: |
3022 次 |
| 最近记录: |