为什么这个添加被默默地忽略了?

use*_*783 14 c compiler-errors visual-c++ language-lawyer constant-expression

我有以下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]);
}
Run Code Online (Sandbox Code Playgroud)

如果我使用Microsoft Visual Studio Community 2015编译它(作为C或C++)然后运行它,输出类似于以下内容:

013E9154 13e9154 13e9154
Run Code Online (Sandbox Code Playgroud)

看起来,+ 0x8000000000000000我希望设置高位的代码a[1]已经被默默地忽略了.

但是,如果我移动a内部的初始化main,输出就是我所期望的:

00179154 179154 8000000000179154
Run Code Online (Sandbox Code Playgroud)

有了a全球性,为什么要默默地忽略这个添加?尝试添加是否应该实际设置高位a[1]或是否应该导致编译器错误?

有趣的是,如果+ 0x8000000000000000上面的代码被替换为| 0x8000000000000000,我得到"错误C2099:初始化程序不是常量".

编辑:即使没有强制转换,也会出现类似的问题.编译为x64,以下代码打印相同的值(例如000000013FB8D180)三次:

#include <stdio.h>

int i;
int * a[] = { &i, &i + 0x100000000 };

int main() {
    printf("%p %p %p\n", &i, a[0], a[1]);
}
Run Code Online (Sandbox Code Playgroud)

nwe*_*hof 1

初始化器

(uint64_t)&i + 0x8000000000000000
Run Code Online (Sandbox Code Playgroud)

不是C 中有效的常量表达式。它也不是允许整型常量、浮点常量、枚举常量、字符常量和 sizeof 表达式作为操作数的算术常量表达式;也不是不允许转换为整数类型的地址常量。

也就是说,我希望 Visual Studio 生成“错误 C2099:初始化程序不是常量”,就像| 0x8000000000000000.

不过我对 C++ 不太确定。