地址与C中静态初始化程序中地址的表达式

时间:2014-10-02 13:18:59

标签: c

(这个问题的灵感来自于调查早期的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)

1 个答案:

答案 0 :(得分:3)

C语言的常量表达式的正式定义允许将整数值转换为指针类型(以形成地址常量),但不是相反(形成< em>算术常量表达式)。它明确指出“算术常量表达式中的转换运算符只能将算术类型转换为算术类型”。因此,(uintptr_t) &memory_area位违反了对算术常量表达式的要求。表达式在形式上不是常量表达式,因此不能在具有静态存储持续时间的对象的初始化程序中使用。

因此,简而言之,&memory_area地址常量,但(uintptr_t) &memory_area不是算术常量表达式

但是,看到海湾合作委员会不允许它作为延期,确实很奇怪。