c - 为什么我不能用其他静态常量指针初始化静态常量指针?

标签 c pointers static initialization constants

我不完全确定以下内容是否会阻碍 C 标准,但 clang 允许使用另一个静态 const 标量 的内容初始化 static const 标量 类型变量变量,示例:

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; 

这听起来很可怕,更不用说我不完全确定它有多安全,因为我不知道链接器/加载器是否可以/将更新地址......

关于如何或即使可以用另一个静态常量指针的内容初始化静态常量指针的任何想法......更准确地说,我正在尝试使用函数指针,但注意到其他指针也有同样的事情类型...

最佳答案

以下是涵盖此内容的文本:

C11 6.6/7:

More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following:

  • an arithmetic constant expression,
  • a null pointer constant,
  • an address constant, or
  • an address constant for a complete object type plus or minus an integer constant expression.

C11 6.6/9:

An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator; it shall be created explicitly using the unary & operator or an integer constant cast to pointer type, or implicitly by the use of an expression of array or function type. The array-subscript [] and member-access . and -> operators, the address & and indirection * unary operators, and pointer casts may be used in the creation of an address constant, but the value of an object shall not be accessed by use of these operators.

C11 6.6/10:

An implementation may accept other forms of constant expressions.

因此,您的 temp 不符合地址常量的条件,因为它不满足地址常量定义中的任何选项。

理由: IDK,这对我来说似乎是一个疏忽。也许是为了避免给编译器带来不必要的负担;例如如果 (void *)1000 实际上并不指向对象(例如,它指向进程的地址空间之外,或者是陷阱表示),则计算 temp 会导致未定义的行为(无需诊断)。

解决方法:使用unsigned long long不如使用uintptr_t。然而,

static const long *const temp1 = (void *)1000; 

似乎是比整数选项更好的选择。您可以使用#define 宏来避免重复实际地址。

关于c - 为什么我不能用其他静态常量指针初始化静态常量指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25838879/

相关文章:

c++ - 为什么递增指针会给出随机数而不是内存地址?

c - 指向嵌套结构中的结构的指针

c - 尝试查找一行中单词的索引(以单词数衡量)

javascript - 除了绑定(bind)之外,任何其他解决方案都可以解决 promise 中的上下文问题

java - 为什么不使用 google.gson.GsonBuilder JSON 解析器序列化静态字段?

c - 每个数字的输出都一样吗?

c++ - 在套接字 C/C++ 上发送浮点值

无法让 realloc() 工作

c - 用于创建 API 的 wchar_t 与 char

c# - 静态构造函数调用两次