Ошибка VS2010 при передаче 64-разрядного перечисления в Printf

#c #visual-studio-2010 #enums #compiler-bug

#c #visual-studio-2010 #перечисления #ошибка компилятора

Вопрос:

Какой-то странный результат, обнаруженный в VC 2010:

 enum dow :unsigned long long {mon=0x800022223333ULL,tue};
int _tmain(int argc, _TCHAR* argv[])
{
    dow a=mon;
    unsigned long long b=0x800022223333ULL;
    printf("%dn",sizeof(a));
    printf("%llxn",a); // a is 32bit or 64 bit???
    printf("%llxn",(unsigned long long)a);
    printf("%llxn",b);
    return 0;
}
  

Я получил неожиданный результат:

 8
1ff1d3f622223333
800022223333
800022223333
  

1ff1d3f622223333 Неверно. После проверки сгенерированного ассемблерного кода я обнаружил, что компилятор передавал 32-разрядный 0x22223333 в printf для a , который затем был неправильно интерпретирован как 64-разрядный спецификацией формата printf. Следовательно, был вставлен мусор 1ff1d3f6 . Почему это так?

РЕДАКТИРОВАТЬ забыл сказать, что он был скомпилирован как 32-разрядный exe-файл с конфигурацией выпуска и отладки.

Комментарии:

1. VS2015 выдает одинаковый результат во всех трех случаях.

2. тогда, скорее всего, ошибка с VC 2010

3. AlexD, вы скомпилировали код как 32-разрядный exe в VS2015?

4. Да, как 32, так и 64 в конфигурациях отладки и выпуска.

Ответ №1:

Похоже, это ошибка в этой версии Visual Studio. Следующий код:

 #include <cstdio>

enum dow :unsigned long long {mon=0x800022223333ULL,tue};
int main()
{
    dow a=mon;
    unsigned long long b=0x800022223333ULL;
    printf("%dn",sizeof(a));
    printf("%llxn",a); // a is 32bit or 64 bit???
    printf("%llxn",(unsigned long long)a);
    printf("%llxn",b);
    return 0;
}
  

выдает аналогичный результат в VS2010:

 8
22223333
800022223333
800022223333
  

Однако, похоже, что это было исправлено в более поздних версиях, тот же код, выполняемый в VS2015 Express, выдает:

 8
800022223333
800022223333
800022223333
  

Поскольку в нашей версии VS2010 установлены все исправления, похоже, что в этой версии это никогда не исправлялось. Поэтому мое предложение (если вам действительно нужны эти большие перечисления) заключается в обновлении.