(这个问题的灵感来自调查一个更早的 question )
我有一个初始化两个全局静态变量的代码示例:一个是指向外部变量的指针,另一个是从该指针计算的表达式:
#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)
最佳答案
C 语言的常量表达式 的正式定义允许将整数值转换为指针类型(形成地址常量),但不能反过来(形成< em>算术常量表达式)。它明确指出“算术常量表达式中的强制转换运算符只能将算术类型转换为算术类型”。为此,(uintptr_t) &memory_area
位违反了对算术常量表达式 的要求。该表达式在形式上不是常量表达式,因此不能在具有静态存储持续时间的对象的初始化程序中使用。
所以,简而言之,&memory_area
是一个地址常量,但是(uintptr_t) &memory_area
不是一个算术常量表达式.
但是看到GCC不允许它作为扩展确实很奇怪。
关于c - C中静态初始值设定项中的地址与地址表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26161764/