2017-01-18 5 views
1

Visual Studio 2013 выдает напрягает (и, казалось бы, не имеет значения) предупреждения компиляции на:VS предупреждение сборник: результат 32-битового сдвига неявно преобразуется в 64 бита

#include <stdint.h> 

#define PRECISION 16 

uint64_t hi = 0; 
for (uint8_t i = 0; i < PRECISION; i++) 
{ 
    if (some_condition) 
    { 
     hi += 1 << (PRECISION - 1 - i); 
    } 
} 

Вот предупреждение сборник:

warning C4334: '<<' : 
result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) 

Кажется, что было разрешено при изменении 1 << (PRECISION - 1 - i) до 1 << (PRECISION - 1).

Так что я пытался выяснить, что может пойти не так, как в 1 << (PRECISION - 1 - i).

Очевидно, что если i >= PRECISION, то операция shift-left приведет к неопределенному поведению.

Однако переменная i не превышает значение PRECISION - 1.

Кроме того, даже если предположить, что компилятор не может это сделать, я не вижу, что это предупреждение компиляции связано с потенциальным неопределенным поведением из-за сдвига-левого операнда.

Возможно, это предполагает, что беззнаковое значение PRECISION - 1 - i может быть больше, чем 31.

Но как именно я должен сказать компилятору, что он никогда не делает?

Я нашел one related question, но нет надлежащих ответов.

Благодаря

ответ

1

Компилятор indeed suspects, что 64-битный предназначалось:

В результате 32-битового сдвига неявно преобразуется в 64 бит, а компилятор подозревает, что 64-битный сдвиг в был предназначен. Чтобы устранить это предупреждение, используйте либо 64-битный сдвиг, либо явно передайте результат сдвига в 64-разрядный.

Вы можете рассмотреть

hi += 1i64 << (PRECISION - 1 - i); 

Возможно удаление i подавляет предупреждение, потому что выражение компилятор трактует как константа.

3

Компилятор жалуется, потому что вы храните результат в 64-битной переменной, поэтому предполагает, что вы действительно хотите выполнить 64-битный сдвиг вместо 32-битного сдвига. Вы можете исправить это, используя

hi += 1ULL << (PRECISION - 1 - i); 

Чтобы заставить его быть 64-битным сменом.

Он также не пожаловался, если hi был unint32_t.

+0

Итак, почему предупреждение очищается, когда я меняю «ТОЧНОСТЬ - 1 - i» на «ТОЧНОСТЬ - 1» (сохраняя при этом результат в 64-битной переменной) ??? –

+0

@barakmanos Мое предположение такое же, как у Алекса. '1 << PRECISION - 1' - это константа времени компиляции, поэтому она, вероятно, оптимизирована до' hi + = constant'. – NathanOliver

+0

Да, оба ответа говорят то же самое ... –

 Смежные вопросы

  • Нет связанных вопросов^_^