Так как в этой ситуации у компилятора есть все, что ему нужно для статической проверки того, что вызов act(5, 5)
не переполняется для предоставленных значений, является ли это стандартно-совместимым поведением для сбоя в этом коде?
Да. Компилятору разрешено выполнять сужающее преобразование только тогда, когда он может гарантировать, что значение представимо в более узком типе. Если бы у вас было
std::array<unsigned char, 2> foo = {5, 127};
, тогда это было бы хорошо, потому что компилятор знает, что 5
и 127
представимы. Ваш случай, хотя не то же самое. Вы выполняете инициализацию внутри функции, а внутри функции {aArgs...}
нет такой же гарантии, поскольку она не является константным выражением (переменные, переданные в функцию, не являются константными выражениями). Из-за этого компилятор не может доказать во всех случаях, что он будет действительным, поэтому он выдает предупреждение / ошибку.
Поскольку для получения литерала без знака нет суффикса, как обойти это решениеэтот баг ||исправить этот нестандартный код?
Вы можете заставить своего собственного пользователя определять литералы для создания беззнаковых символов, таких как
inline constexpr unsigned char operator ""_uc( unsigned long long arg ) noexcept
{
return static_cast< unsigned char >( arg );
}
//...
act(5_uc, 5_uc);
, или вы можете просто приводить их как
act((unsigned char)5, (unsigned char)5);
Фактическая формулировка, которая охватывает этот случай, может быть найдена в [dcl.init] / 7
Сужающее преобразование - это неявное преобразование [. ..}
- из целочисленного типа или перечислимого типа с незаданной областью в тип с плавающей запятой, за исключением , где источником является константное выражение , а фактическое значение после преобразования помещается вцелевой тип и будет производить исходное значение при преобразовании обратно в исходный тип [...]
выделение мин
Как вы можетевидите, инициализатор должен быть константным выражением. Поскольку параметры функции никогда не являются константными выражениями, не имеет значения, сколько статического анализа выполняет компилятор и сколько у него доказательств. Это не константное выражение, поэтому его нельзя сделать.