Pull to refresh
108.25
PVS-Studio
Статический анализ кода для C, C++, C# и Java

Мы иногда во внутреннем чате обмениваемся фрагментами кода с неочевидными ошибками, которые обнаруживаются с помощью 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");
Tags:
Total votes 29: ↑28 and ↓1+30
Comments16

Articles

Information

Website
pvs-studio.ru
Registered
Founded
2008
Employees
51–100 employees
Location
Россия
Representative
Андрей Карпов