为什么我不能用其他静态const指针初始化一个静态const指针?

时间:2014-09-14 23:05:28

标签: c pointers static initialization const

我不完全确定以下是否制动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指针的任何想法...更准确地说我正在尝试使用函数指针,但注意到与其他指针相同的事情类型...

1 个答案:

答案 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宏来避免重复实际地址。