GCC и -Wconversion - PullRequest
       8

GCC и -Wconversion

0 голосов
/ 15 января 2019

Давайте скомпилируем следующую программу:

int main()
{
    uint16_t data = 0;
    data |= uint16_t(std::round(3.14f));
    return 0;
}

с g++ -Wconversion prog.cpp

Мы получим warning: conversion to ‘uint16_t {aka short unsigned int}’ from ‘int’ may alter its value, но я не вижу здесь неявных преобразований.

Предупреждения такого рода должны быть отключены явным приведением, например:

double d = 3.14;
float foo1 = d; // Warning
float foo2 = float(d); // No warning
float foo2 = static_cast<float>(d); // No warning

GCC здесь или это ошибка?

Обратите внимание, что мой фрагмент минимален.Например, предупреждение исчезает в следующих случаях:

  • убрать суффикс f из 3.14, т.е. сделать его double
  • использовать назначение вместо |=
  • удалить std::round
  • результат округления в кэш: const auto r = uint16_t(std::round(3.14f));, затем или присвоить его data.

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Предупреждение ложное.

Согласно [перестроено] / 22 * ​​1004 *:

Для каждой тройки ( L, VQ, R ), где L является целочисленным типом, VQ является либо летучим, либо пустым, а R - повышенный целочисленный тип, существуют операторные функции-кандидаты вида ...

VQ L&   operator|=(VQ L&, R);

Итак, мы получаем встроенный unsigned short operator |=(unsigned short&, unsigned int);

В данном выражении нет неявных преобразований

uint16_t data = 0;
data |= uint16_t(std::round(3.14f));
0 голосов
/ 18 января 2019

GCC прямо здесь или это ошибка?

Поскольку поведение не соответствует ожиданиям, я бы назвал это ошибкой.

С https://godbolt.org/z/aSj--7, кажется, что в глазах GCC data |= uint16_t(std::round(3.14f)) переводится как

(void) (data = TARGET_EXPR <D.2364, (uint16_t) round (3.1400001049041748046875e+0)>;, data | NON_LVALUE_EXPR <D.2364>;)

(TARGET_EXPR представляет временный объект. D.2364 - имя внутренней переменной.)

Переведите внутренний язык GCC обратно на C ++, и мы получим

data = (temp = (uint16_t) round (3.14e+0), data | temp)

Поскольку LHS выражения с запятой не влияет на RHS, это должно быть так же безопасно, как и data = data | temp. Тем не менее, GCC предупреждает в первом, но не во втором, что вряд ли будет преднамеренным Таким образом, я считаю, что это недосмотр сопровождающих GCC.

...