C笔记-编译错误:'XXX'的存储大小不是常量

作者:聂勇 欢迎转载,请保留作者信息并说明文章来源!

环境 | Enviroment

  • 操作系统:RedHat 5.7 64bit
  • GCC: 4.1.2

问题及解决方法 | Problem and solution

问题描述

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const char *formatTime(time_t time){
if (0 == time) {
return "";
}
const int TIME_SIZE = 20;
static char result[TIME_SIZE];
struct tm *timeStruct = localtime(&time);
size_t len = strftime(result, TIME_SIZE, "%Y-%m-%d %H:%M:%S", timeStruct);
if (0 == len) {
fprintf(stderr, "execute function strftime fail");
}
return result;
}

编译警告信息:

./Stat.c: In function ‘formatTime’:
./Stat.c:85: 错误:‘result’ 的存储大小不是常量

原因

1)这个问题其实是“常量”与“只读变量”的区别。常量肯定是只读的,例如5, “abc”等是只读的,不能够修改。而“只读变量”则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符(Qualifier)。上述代码中变量TIME_SIZE被修饰为只读变量,可惜再怎么修饰也不是常量。而ANSI C规定数组定义时维度必须是“常量”,“只读变量”也是不可以的。
2)在ANSI C中,这种写法是错误的,因为数组的大小应该是个常量,而const int n,n只是一个变量(常量 != 不可变的变量,但在标准C++中,这样定义的是一个常量,这种写法是对的),实际上,根据编译过程及内存分配来看,这种用法本来就应该是合理的,只是 ANSI C对数组的规定限制了它。
3)在ANSI C 语言中用#define宏来定义常量。

解决方法

用#define代替const定义常量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define TIME_SIZE 20
... ... ... 省略部分代码 .........
const char *formatTime(time_t time){
if (0 == time) {
return "";
}
static char result[TIME_SIZE];
struct tm *timeStruct = localtime(&time);
size_t len = strftime(result, TIME_SIZE, "%Y-%m-%d %H:%M:%S", timeStruct);
if (0 == len) {
fprintf(stderr, "execute function strftime fail");
}
return result;
}