c - C中静态初始值设定项中的地址与地址表达式

标签 c

(这个问题的灵感来自调查一个更早的 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/

相关文章:

c - 为什么 sizeof run on struct 必须有括号

c - 引用函数内的引用函数

c# - 创建数据库时如何指定 ODBC Access Driver Format

C 将 void 指针转换为函数指针

c - 在 Windows 中创建线程时不兼容的类型

C 文件访问字数

c - 使用 WinAPI 在 C 中获取当前用户的桌面路径

c - C 中指向 void 指针的指针 - 我可以使用 void** 进行基本的多态性吗?

c - 打印此二进制代码...向后。在 C

为多个作者在管道中交错的 block ?