(C++11) g++ не выдает надлежащего предупреждения, если типы cstdint используются "неправильно"

Сегодня я пробовал некоторые типы, определенные в заголовочном файле cstdint:std::uint16_t, std::uint_least16_t и так далее..

Я думаю, что они очень полезны, потому что вы точно знаете или, по крайней мере, насколько они велики, в отличие от более распространенных платформо-зависимых: int, unsigned intи т. д. Но есть одна проблема, которая, я думаю, может вызвать много ошибок.

Допустим, у нас есть этот код:

#include <cstdint>
#include <iostream>

int main()
{
  std::uint_fast16_t test = 0;

  test = 65536;

  std::cout << test;

  return 0;
}

Мы знаем это std::uint_fast16_t должно быть как минимум 2 байта.

Если uint_fast16_t ровно 2 байта, этот код выдает предупреждение из-за переполнения. Но в моем случае uint_fast16_t составляет 8 байт (проверено ранее).

Так что в моем случае этот код компилируется и работает нормально, в другом мы получаем предупреждение. Наш код не является переносимым. Это просто неправильно для меня. Даже если переменная может содержать эти данные, компилятор должен по крайней мере дать нам предупреждение или предложить нам использовать больший тип. Я прав? Или я неправильно понял цель этих типов?

Я скомпилировал код, используя g++ с этими флагами

-Wall -Werror -pedantic -std= C++0x

1 ответ

Решение

Компилятор не может выдавать никаких других предупреждений, потому что эти типы являются typedefs и обрабатываются в точности как типы, к которым они синонимы. Вот как работает C++. У тебя есть UINT_FAST16_MAX и, возможно, std::numeric_limits<std::uint_fast16_t>::max() чтобы сказать вам максимальное значение, которое может содержать этот тип. Ваша работа - использовать эту информацию.

Также имейте в виду, что большинство типов, определенных stdint, на самом деле являются необязательными, поэтому просто используя их и не проверяя, существуют ли они, вы делаете свой код непереносимым.

Другие вопросы по тегам