Ситуация:
У меня есть часть кода, которая работает, когда скомпилирована для 32-битных, но сбой при компиляции для 64-бит с gcc 4.6. После определения проблемы и чтения стандартов, я не могу понять, почему он работает для 32-бит. Надеюсь, кто-то может объяснить, что происходит.
Код (несколько упрощен и сокращен до интересных частей):
// tbl: unsigned short *, can be indexed with positive and negative values
// v: unsigned int
// p: unsigned char *
tmp = tbl[(v >> 8) - p[0]]; // Gives segfault when not compiled with -m32
При компиляции с -m32
работает код. При компиляции без -m32
он дает segfault. Причиной segfault является то, что (v >> 8) - p[0]
интерпретируется как unsigned int
при компиляции для 64-битного, что для "отрицательных" результатов будет отключено.
Согласно этому вопросу, в стандарте C99 говорится следующее:
6.2.5c9: A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.
Похоже, что unsigned
минус unsigned
всегда будет выводить вывод unsigned
, который согласуется с тем, что происходит в 64-битном случае. Это, похоже, не случается в 32-битном случае, что я считаю чрезвычайно странным.
Может ли кто-нибудь объяснить, что происходит в 32-битном случае?