【发布时间】:2018-08-09 16:52:25
【问题描述】:
我有一段代码定义(我认为是)一个空数组,即一个不包含元素的数组:
int a[] = {};
我用gcc编译sn-p没有问题
一位试图在 MSVS 下编译相同代码的同事进行了修改:
int* a = NULL;
不,他显然认为这是 MSVS 编译器可以接受的等效语句。
但是,稍后在代码中我检索到编号。数组中的元素使用以下宏:
#define sizearray(a) (sizeof(a) / sizeof((a)[0]))
这样做时:
sizearray({}) returns 0
正如我所期望的那样,我认为这是一个空数组的定义
sizearray(NULL) returns 1
我认为sizeof(NULL)/sizeof((NULL)[0])) 实际上是4/4 == 1
作为NULL == (void*)0
我的问题是:
int a[] = {};
是表达空数组的有效方式,还是它的编程习惯不好。
另外,您是否不能在 MSVS 编译器中使用这样的表达式,即这是某种 C99 兼容性问题?
更新:
刚刚编译了这个:
#include <stdio.h>
#define sizearray(a) (sizeof(a) / sizeof((a)[0]))
int main()
{
int a[] = {};
int b[] = {0};
int c[] = {0,1};
printf("sizearray a = %lu\n", sizearray(a));
printf("sizearray b = %lu\n", sizearray(b));
printf("sizearray c = %lu\n", sizearray(c));
return 0;
}
使用这个 Makefile:
array: array.c
gcc -g -o array array.c
我的编译器是:
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
编译没有任何问题,输出如下:
bph@marvin:~/projects/scratch/c/array$ ./array
sizearray a = 0
sizearray b = 1
sizearray c = 2
很好奇?会不会偷偷是C++编译器,而不是C编译器?
尝试了 John Bodes 对其他编译器标志的建议,并且可以确认编译确实失败了:
gcc --std=c11 --pedantic -Wall -g -o array array.c
array.c: In function ‘main’:
array.c:7:15: warning: ISO C forbids empty initializer braces [-Wpedantic]
int a[] = {};
^
array.c:7:9: error: zero or negative size array ‘a’
int a[] = {};
^
Makefile:2: recipe for target 'array' failed
make: *** [array] Error 1
【问题讨论】:
-
不 - 让我仔细检查一下!
-
很有可能..
-
这里没有数组。
-
将标志
--std=c11 --pedantic --Wall添加到您的 gcc 命令中,您会收到警告。 -
@bph -
-Wall -Werror应该在 IMO 的每个构建命令中 - 它会打开所有警告,并使所有警告错误,这意味着您必须在代码将构建。这并不总是现实的(一些旧的 API 会在较新的编译器中触发警告),但它至少应该是一个起点。--pedantic将拒绝大多数(不是全部!)编译器扩展,提供最大的可移植性。但是,有时您需要这些扩展。
标签: c arrays visual-studio gcc