在C语言中,常量大小的全局数组

4

我正在尝试找出定义具有固定大小的全局数组的最佳方式,以下是我找到的选项,每个选项都有其自身的缺陷。

// 1:
#define ASIZE 10
int array[ASIZE];

// 2:
enum {ASIZE = 10};
int array[ASIZE];

// 3:
#define ASIZE_DEF 10
static const int ASIZE = ASIZE_DEF;
int array[ASIZE_DEF];

第一种和第二种方法的问题在于我无法从 GDB 中获取 ASIZE 的值。我猜第三种选项是最好的,因为我仍然可以转储 const 的值,但它也会泄漏另一个宏。我可以在定义数组和 const 后取消定义宏,但如果 #define 和 const 在与数组声明不同的文件中,则会变得有些棘手。
有更好的方法吗?

数字3应该做什么?static变量只会带来“未使用的变量”警告,对吧? - Jens Gustedt
@JensGustedt GCC没有抱怨 - dschatz
@JensGustedt实际上,在C语言中,“static”表示局部于编译单元(=模块=目标文件)。它是“extern”的相反。 由于变量的默认值为“static”(函数的默认值为“extern”),因此明确声明变量为“static”不会改变任何内容,但对于阅读代码的程序员来说,这可能是一个很好的语义补充。 请注意,声明符号“static”意味着编译器实际上可以检查它是否被使用,因为它看到符号生命周期的整个范围。因此会出现“unused *”警告。 - Jan Smrčina
4个回答

8
为了调试器而做某事是错误的。顺便提一下,如果您编译代码正确,gdb知道这个

一些语言(例如C和C ++)提供了定义和调用“预处理宏”的方法,这些宏会扩展为令牌字符串。 gdb可以评估包含宏调用的表达式,显示宏扩展的结果,并显示宏的定义,包括其定义位置。

gcc 3.1及更高版本的gnu C编译器提供宏信息,如果您指定选项-gdwarf-2-g3;前者请求Dwarf 2格式的调试信息,后者请求“额外的信息”。


我刚刚尝试了一下,但无法在gdb中获取预处理器宏。你能演示一下吗? - dschatz
我查了一下,这似乎在OS X上不起作用。这可能是gcc/gdb的问题。 - dschatz
@dschatz 那个gcc是哪个版本?它是否对-g3等参数报错? - cnicutar
拥有符号不仅仅是为了调试器。它还支持动态库的可升级性(因为常量未编译到客户端程序中),以及与非C语言的FFI交互。 - Kevin Reid

5

您遇到的是 GDB 问题,而不是 C 语言问题。您也可以尝试 #4 方法,这可能比 #3 更好。

enum {ASIZE = 10};
static const int ASIZE_FOR_GDB = ASIZE;
int array[ASIZE];

5
我的理解是,您正在定义一个常量,并在以后使用它来调整一个或多个数组的大小,同时希望该常量成为一个符号,最好不要使用混乱的命名空间。(如果只是导出一个单独数组的大小,我建议像missingno一样使用sizeof(array) / sizeof(*array)
static const int ASIZE = 10;
#define ASIZE            10
int array[ASIZE];

在这里,有一个变量具有所需的值,该值将在对象文件中,但是预处理器宏用值本身遮蔽了它,因此数组定义也成功了。
然而,您可能会发现需要复制值表达式很丑陋。如果我们可以基于宏来定义变量,那不是很好吗?
static const int ASIZE =
#define ASIZE 10
                         ASIZE;
int array[ASIZE];

我不确定这种方法在可维护性方面是否比上面的更好,但它能够工作(而且我没有让gcc感到反感),并且除标识符外没有重复。而且很有趣。


2

由于您知道array是一个全局数组(而不仅仅是指针),因此可以使用以下方法找到其长度:

sizeof(array) / sizeof(*array)

无需设置额外变量即可完成此操作。

1
我觉得这并不特别适用。如果我将数组定义为一些常量算术表达式的大小,会怎样呢?我的意思是,我想要常量的值,关于数组的问题只是我不能单独使用 const。 - dschatz
如果数组大小由常量表达式定义,则sizeof方法仍应该起作用。虽然它不显示常量的值,但如果您只关心长度,那就足够了。 - hugomg
我的观点是,数组的大小不是问题,纯粹是常量值的问题。我只是提出全局数组的情况,因为这样我就无法仅使用单个常量,否则这将是理想的选择。 - dschatz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接