不能把const对象用在常量表达式中
问:为什么不能把const
对象用在常量表达式中呢?“constant”不就是常量吗?
答:在C
语言中,const
表示“只读”而不是“常量”。下面用几个例子说明为什么const
对象不能用于常量表达式。
首先,const
对象只在它的生命期内为常量,而不是在程序的整个执行期内。假设在函数体内声明了一个const
对象:
void f(int n)
{
const int m = n / 2;
...
}
当调用函数f
时,m
将会被初始化为n/2
,m
的值在函数f
返回之前都保持不变。当再次调用函数f
时,m
可能会得到不同的值。这就是出现问题的地方。假设m
出现在switch
语句中:
void f(int n)
{
const int m = n / 2;
...
switch (...) {
...
case m: ... /*** wrong ***/
...
}
...
}
那么直到函数f
调用之前m
的值都是未知的,这违反了C
语言的规则——分支标号的值必须是常量表达式。
接下来看看声明在块外部的const
对象,这些对象具有外部链接,并且可以在文件之间进行共享。如果C
语言允许在常量表达式中使用const
对象,我们很容易遇到下列情况:
extern const int n;
int a[n]; /*** wrong ***/
n
可能在其他文件中定义,这使编译器无法确定数组a
的长度。(假设a
是外部变量,所以它不可能是变长数组。)
如果这样还不能让你信服,考虑下面的情况:如果一个const
对象也用volatile
类型限定符声明,它的值可能 在程序执行过程中的任何时间发生改变。下面是C
标准中的一个例子:
extern const volatile int real_time_clock;
程序可能不会改变变量real_time_clock
的值(因为它声明为const
),但是可以通过 其他某种机制修改它的值(因为它被声明为volatile
)。