我有一个有效的功能,但我想知道为什么static char out[0];
在需要在范围内分配静态内存时不会产生警告?在此示例中,out
的大小的正确值是什么?:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *hex(char *s)
{
int i, l = (int)strlen(s);
static char out[0]; // should it be 7 ?
for(i = 0; i < l; i++) {
s[i] -= 5;
sprintf(&out[i*6], "0x%02x, ", (unsigned char)s[i]);
}
return out;
}
int main(void)
{
char s[] = "hello";
printf("%s", hex(s)); // 0xa8, 0xa5, 0xac, 0xac, 0xaf,
return 0;
}
答案 0 :(得分:3)
我知道没有C编译器为越界数组访问提供警告。您可以自己确保数组索引处于边界内。
答案 1 :(得分:3)
我认为你必须使用malloc动态分配:
char *out = malloc(6 * strlen(s) + 1); // 6 = strlen("0xXX, ")
并且在使用它之后不要忘记释放“out”
答案 2 :(得分:1)
为什么静态char out [0];不会抛出警告
这是undefined behavior来指定零大小的数组,并且编译器没有义务在这种情况下生成诊断。如果我们查看C99 draft standard部分6.7.5.2
数组声明符段 1 说(强调我的):
[..]如果它们分隔表达式(指定数组的大小),则 表达式应具有整数类型。 如果表达式是常量表达式,则其值应大于零。[...]
虽然gcc
会在这种情况下警告您使用-pedantic
标志,但我会收到以下警告:
警告:ISO C禁止零大小数组'out'[-pedantic]
如果它也 undefined 来访问一个超出界限的数组,这里也适用于警告。
如果我们在段落 2 中的3.4.3
部分中查看未定义行为的定义(强调我的):
注意可能的未定义行为包括完全忽略具有不可预测结果的情况,在翻译或程序执行期间以环境特有的文档形式表现(有或没有发出诊断消息) ,终止翻译或执行(发布诊断信息)。
对输出使用static
变量是一个有问题的设计,这意味着该方法的每个调用者将共享相同的输出。一个更好的选择是使用 malloc 来动态分配内存,这意味着你必须在完成后记住释放内存。