我不完全确定以下是否制动C标准,但是clang允许用另一个静态const scalar
变量的内容初始化静态const scalar
类型变量,例如:
static const long temp = 10;
static const long temp1 = temp;
当我尝试使用指针时,它会失败。
static const long *const temp = (void *)1000; // ok
static const long *const temp2 = (void *)&temp2; // ok
static const long *const temp1 = temp;
// ^^^^ error: initializer element is not a compile-time constant
一种方法可以简单地使用long或任何其他标量类型来保存地址......
static unsigned long long temp;
static const unsigned long long addr = (unsigned long long)&temp;
static const unsigned long long addr2 = addr;
这听起来很恐怖,更不用说我不完全确定它有多安全,因为我不知道链接器/加载器是否可以/将更新地址......
关于如何甚至可以用另一个静态const指针的内容初始化一个静态const指针的任何想法...更准确地说我正在尝试使用函数指针,但注意到与其他指针相同的事情类型...
答案 0 :(得分:2)
以下是涵盖此内容的文字:
C11 6.6 / 7:
初始值设定项中的常量表达式允许更多纬度。这样的常量表达式应为或评估为以下之一:
- 算术常量表达式
- 一个空指针常量,
- 地址常量,或
- 完整对象类型的地址常量加上或减去整数常量 表达
C11 6.6 / 9:
地址常量是一个空指针,指向一个指定静态对象的左值的指针 存储持续时间,或指向功能指示符的指针;它应该使用明确创建 一元& 运算符或整数常量强制转换为指针类型,或隐式使用 数组或函数类型的表达式。数组下标 [] 和成员访问。 和 - > 运算符,地址& 和间接 * 一元运算符和指针强制转换 用于创建地址常量,但对象的值不应该是 通过使用这些运算符访问。
C11 6.6 / 10:
实现可以接受其他形式的常量表达式。
因此,您的temp
不符合地址常量,因为它不满足地址常量定义中的任何选项。
理由: IDK,这似乎是对我的疏忽。也许是为了避免给编译器带来不必要的负担;例如如果(void *)1000
实际上没有指向某个对象(例如,它指向进程的地址空间之外,或者是陷阱表示),则评估temp
会导致未定义的行为(无需诊断)。
解决方法:使用unsigned long long
不如使用uintptr_t
。但是,
static const long *const temp1 = (void *)1000;
似乎比整数选项更好。您可以使用#define
宏来避免重复实际地址。