数组的外部声明

extern declaration of array

我有一个数组,其大小是在 compile-time 期间在源文件中定义的。

const int array[] = {1, 3, 3, 7};

未来元素的数量可能会发生变化,所以我不想将其硬编码在括号中。

需要从多个源文件访问此数组,因此我试图在 header 中向其添加外部声明。但是,由于隐式数组大小,我不确定这是可能的。我尝试了两种变体:

extern const int array[]; // Warning: size of symbol `array' changed from 8 to 16
extern const int *array; // error: conflicting types for 'array'

是否可以这样做,或者我应该寻找 work-around?

在声明变量的header中,写:

extern const int array[];

不过你是对的,其他文件不知道数组的大小。那更棘手。您可能会在 header:

中使用
extern const int array[];
extern const size_t array_size;

以及定义数组的位置:

const int array[] = {1, 3, 3, 7};
const size_t array_size = sizeof(array) / sizeof(array[0]);

您将在定义数组的位置包括 header 以确保 cross-references 是正确的,一致。如果您选择使用 int 而不是 size_t,您不会收到我的任何投诉(但如果您将编译器设置得足够挑剔,它可能对这个问题有不同的看法)。

注意数组大小不是标准意义上的'integer constant';例如,它不能用于 case 标签。如果您使用 array_size 声明另一个数组,它将是一个 VLA — 可变长度数组。此类数组不能在文件范围内声明(或在函数内使用 static 存储 class)。

另见 How do I use extern to share variables between source files?

插图

一个 MCVE (Minimal, Complete, Verifiable Example) 的答案:

ext-def.h

#include <stddef.h>

extern const int array[];
extern const size_t array_size;

ext-def.c

#include "ext-def.h"

const int array[] = {1, 3, 3, 7};
const size_t array_size = sizeof(array) / sizeof(array[0]);

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;
}

编译

在 MacBook Pro 上使用 GCC 7.2.0 运行 macOS High Sierra 10.13.2,使用 martinkunev in a comment 指定的选项:

$ 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
$

使用我的默认编译选项(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
$

在任何一组选项下都warning-free。您也可以在 C11 命令行中添加 -pedantic 而不会收到任何警告。