У меня есть следующий код 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]);
}
Если я скомпилирую это (как C или как С++) с Microsoft Visual Studio Community 2015, а затем запустил его, результат будет похож на следующий:
013E9154 13e9154 13e9154
Кажется, что код + 0x8000000000000000
, который, как я ожидал, установил высокий бит a[1]
, был молча игнорирован.
Однако, если я перемещаю инициализацию a
внутри main
, вывод будет тем, что я ожидал бы:
00179154 179154 8000000000179154
С 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]);
}