(这个问题的灵感来自于调查早期的question)
我有一个初始化两个全局静态变量的代码示例:一个是指向extern变量的指针,另一个是从该指针计算的表达式:
#include <stdint.h>
#define UNCACHE_MASK 0xABCDEF12UL // Value of the mask to apply
extern int memory_area;
const void * virtual_address = &memory_area;
const uintptr_t int_address = ((uintptr_t)&memory_area) | UNCACHE_MASK;
编译时,我得到以下内容:
$ gcc -c test.c
test.c:6:1: error: initializer element is not computable at load time
const uintptr_t int_address = ((uintptr_t)&memory_area) | UNCACHE_MASK;
^
我不是C的专家,但似乎如果&memory area
有助于初始化virtual_address
,那么初始化int_address
也应该有用。
我错过了什么?
(gcc版本4.8.2,Win 7上的Cygwin)
答案 0 :(得分:3)
C语言的常量表达式的正式定义允许将整数值转换为指针类型(以形成地址常量),但不是相反(形成< em>算术常量表达式)。它明确指出“算术常量表达式中的转换运算符只能将算术类型转换为算术类型”。因此,(uintptr_t) &memory_area
位违反了对算术常量表达式的要求。表达式在形式上不是常量表达式,因此不能在具有静态存储持续时间的对象的初始化程序中使用。
因此,简而言之,&memory_area
是地址常量,但(uintptr_t) &memory_area
不是算术常量表达式。
但是,看到海湾合作委员会不允许它作为延期,确实很奇怪。