我有以下C代码:
#include <stdint.h>
#include <stdio.h>
int i;
uint64_t a[] = { (uint64_t)&i, (uint64_t)&i + 0x8000000000000000 };
int main() {
printf("%p %llx %llx\n", &i, a[0], a[1]);
}
如果我使用Microsoft Visual Studio Community 2015编译(作为C或C++),然后运行它,则输出类似于以下内容:
013E9154 13e9154 13e9154
看来我希望将
+ 0x8000000000000000
的高位设置为高的代码a[1]
已被默默地忽略了。但是,如果我将
a
的初始化移到main
内,则输出将是我期望的:00179154 179154 8000000000179154
使用
a
global时,为什么默默地忽略添加项?尝试加法实际上应该设置a[1]
的高位还是应该导致编译器错误?有趣的是,如果将以上代码中的
+ 0x8000000000000000
替换为| 0x8000000000000000
,则会收到“错误C2099:初始化程序不是常量”。编辑:即使没有强制转换,也会发生类似的问题。以下代码针对x64进行了编译,打印了3次相同的值(例如
000000013FB8D180
):#include <stdio.h>
int i;
int * a[] = { &i, &i + 0x100000000 };
int main() {
printf("%p %p %p\n", &i, a[0], a[1]);
}
最佳答案
初始化器
(uint64_t)&i + 0x8000000000000000
在C中不是有效的constant expression。它也不是仅允许将整数常量,浮点常量,枚举常量,字符常量和sizeof表达式用作操作数的算术常量表达式;也不允许不允许转换为整数类型的地址常量。
就是说,我希望Visual Studio像
| 0x8000000000000000
一样生成“错误C2099:初始化程序不是常量”。不过,我不确定C++。