Непоследовательное предупреждение: «преобразование из« const unsigned char »в« const float »требует сужающего преобразования» - PullRequest
0 голосов
/ 25 апреля 2018

Visual C ++ 2017 и gcc 5.4 выдают conversion from 'const unsigned char' to 'const float' requires a narrowing conversion предупреждение для Line B, но не для Line A в этом фрагменте кода:

#include <iostream>

int main() {
    const unsigned char p = 13;
    const float         q = p;  // Line A

    std::cout << q << '\n';

    const unsigned char c[3] = {0, 1, 255};
    const float         f[3] = {c[2], c[0], c[1]};  // Line B

    for (auto x:f)
        std::cout << x << '\n';
}

Это предупреждение действительно? Почему Line B трактуется иначе, чем Line A?

1 Ответ

0 голосов
/ 25 апреля 2018

Предупреждение действительно, из C ++ 11 сужающие преобразования запрещены при агрегированной инициализации ; но не применяется в копировать инициализацию (как раньше).

Если предложение инициализатора является выражением, неявные преобразования разрешаются согласно инициализации копирования , except if they are narrowing (as in list-initialization) (since C++11).

До C ++ 11 сужающие преобразования были разрешены в агрегатной инициализации, но они больше не разрешены.

И

список-инициализация ограничивает допустимые неявные преобразования запрещающий следующее:

  • преобразование из целочисленного типа в тип с плавающей точкой, за исключением случаев, когда источником является константное выражение, значение которого может быть сохранено точно в целевой тип

Кстати: c[0], c[1] и c[2] являются не константными выражениями ; Вы можете объявить массив как constexpr, т.е. constexpr unsigned char c[3] = {0, 1, 255};. Затем применяется исключение, и Линия B тоже будет работать нормально.

...