数组的extern声明

问题描述 投票:1回答:1

我有一个数组,其大小在源文件中定义的编译时确定。

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

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

这个数组需要从几个源文件中访问,所以我试图在头文件中添加一个extern声明。但是由于隐式数组大小,我不确定这是否可行。我尝试了两种变体:

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

是可以这样做还是我应该找一个解决方法?

c99 extern variable-declaration
1个回答
1
投票

在声明变量的标头中,写:

extern const int array[];

但是,你是对的,其他文件不知道数组的大小。那太棘手了。您可能在标题中使用:

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]);

您将包含定义数组的标头,以确保交叉引用是正确的。如果你选择使用int而不是size_t,你将不会得到我的抱怨(但如果你设置你的编译器足够繁琐,它可能对这个主题有不同的看法)。

注意,数组大小不是标准含义内的“整数常量”;例如,它不能用于case标签。如果使用array_size声明另一个数组,它将是一个VLA - 可变长度数组。此类数组不能在文件范围内声明(或在函数内使用static存储类)。

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

Illustration

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

汇编

在运行macOS High Sierra 10.13.2的MacBook Pro上使用GCC 7.2.0,使用martinkunevcomment中指定的选项:

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

在任何一组选项下都同样没有警告。您可以将-pedantic添加到C11命令行,而不会收到任何警告。

© www.soinside.com 2019 - 2024. All rights reserved.