Мы иногда во внутреннем чате обмениваемся фрагментами кода с неочевидными ошибками, которые обнаруживаются с помощью PVS-Studio в каком-нибудь открытом проекте. Мол, кто быстро сообразит, что не так с кодом?
Вчера коллега поделился вот таким фрагментом кода из проекта SereneDB:
template <typename T> struct NumericParameter : public Parameter { using ValueType = T; .... std::string name() const override { if constexpr (std::is_same_v<ValueType, int16_t>) { return "int16"; } else if constexpr (std::is_same_v<ValueType, uint16_t>) { return "uint16"; } else if constexpr (std::is_same_v<ValueType, int32_t>) { return "int32"; } else if constexpr (std::is_same_v<ValueType, uint32_t>) { return "uint32"; } else if constexpr (std::is_same_v<ValueType, int64_t>) { return "int64"; } else if constexpr (std::is_same_v<ValueType, uint64_t>) { return "uint64"; } else if constexpr (std::is_same_v<ValueType, size_t>) { return "size"; } else if constexpr (std::is_same_v<ValueType, double>) { return "double"; } else { static_assert("unsupported ValueType"); } } .... };
Признаюсь честно, я два раза прочитал этот фрагмент, но так и не увидел ошибку. И засчитал себе поражение. Раз так, думаю, это достойно публикации в канал, чтобы и вы могли испытать свою внимательность :)

Ответ:
Анализатор PVS-Studio выдаёт предупреждение V591 Non-void function should return a value. parameters.h 222
На первый взгляд предупреждение странное и смахивает на ложное срабатывание, ведь не может быть, что функция закончила работу, не вернув значение с помощью оператора return. Если выбирается ветка else, то там static_assert, и код просто не должен скомпилироваться. Во всех остальных случаях есть return "что-то";.
Но есть нюанс!
Ещё раз посмотрите на эту строчку:
static_assert("unsupported ValueType");
static_assert используется неправильно: пропущен bool-constexpr. Вернее, строковый литерал неявно конвертируется в значение true, и static_assert никогда не прервёт компиляцию. В итоге else-ветка функции ничего не возвращает, и её поведение будет не определено для всех специализаций NumericParameter, кроме указанных ранее в цепочке if constexpr.
Правильный вариант:
static_assert(false, "unsupported ValueType");