Подтвердить что ты не робот

Сужение списков конверсий и инициализаторов, какой компилятор прав?

Учитывая следующий фрагмент кода:

#include <iostream>

auto main() -> int {
  double x(7.0);
  int i{x};
  std::cout << "i = " << x << std::endl;

  return 0;
}

  • При компиляции в GCC4.9 он компилируется с предупреждением только:

    warning: narrowing conversion of ‘x’ from ‘double’ to ‘int’ inside { }


  • Компиляция с Clang3.3 или VС++ 2013 дает ошибку компиляции:

    error: type 'double' cannot be narrowed to 'int' in initializer list  error C2397: conversion from 'double' to 'int' requires a narrowing


Вопросы:

  • Какой из компиляторов прав в соответствии со стандартом?

  • Есть ли причина, по которой упомянутые выше компиляторы должны проявлять такое разнообразное поведение?

4b9b3361

Ответ 1

Ответ

Оба компилятора верны!


Объяснение

В стандарте не проводится различие между ошибкой и предупреждением, оба входят в категорию диагностики.

1.3.6 диагностическое сообщение [defns.diagnostic]

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

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

Даже если программа плохо сформирована с точки зрения стандартов, она не гарантирует, что компилятор прекратит компиляцию из-за этого; реализация может свободно делать все, что захочет, до тех пор, пока она выдает диагностику.



Причина поведения gcc?

Полезная информация была предоставлена ​​@Jonathan Wakely через комментарии к этому сообщению, ниже - слияние двух комментариев;

он точная причина в том, что GCC сделал ошибку в какой-то момент, и он сломал ВСЕ ПРОГРАММЫ, поэтому вместо этого он превратился в предупреждение. Несколько человек, которые включили опцию -std=c++0x для больших кодовых баз С++ 03, обнаружили безвредные суживающие преобразования, чтобы заставить большую часть работы портирования перейти на С++ 11.

См., Например, PR 50810, где Alisdair сообщает о сужении ошибок, было 95% проблем в базе кода Bloomberg.

В этом тот же PR вы можете видеть, что, к сожалению, это был не случай "давайте просто выпустить предупреждение и сделать с ним", потому что для правильного поведения потребовалось много усилий.