2016-07-24 8 views
99

Если вы хотите использовать Qt, вы должны принять quint8, quint16 и так далее.Почему все typedef над стандартными типами C?

Если вы хотите использовать GLib, вы должны приветствовать guint8, guint16 и так далее.

На Linux есть u32, s16 и так далее.

UC/OS определяет SINT32, UINT16 и так далее.

И если вам нужно использовать какую-то комбинацию этих вещей, вам лучше подготовиться к неприятностям. Потому что на вашей машине u32 будет typedef d над long и quint32 будет typedef d над int и компилятор пожалуется.

Почему все это делают, если есть <stdint.h>? Это какая-то традиция для библиотек?

+0

Для меня вопрос больше не «почему бы им просто не использовать« stdint.h'? », А скорее, было бы, почему кто-нибудь, например. используйте 'UINT16' или' quint16' вместо простого 'unsigned short' в первую очередь? On *, какой именно компилятор точно сделал бы это, провалили бы их? – Mehrdad

+8

@Mehrdad в программировании микроконтроллеров вы можете иметь всевозможные вещи. Например, на AVR Mega (и, следовательно, на знаменитом Arduino) int 16 бит. Это может быть неприятный сюрприз. На мой взгляд, «unsigned short» требует больше усилий для набора текста. И мне всегда было грустно использовать «unsigned char» для байт октет. Беззнаковый персонаж, правда? – Amomum

+0

Да, я знаю об этом, но я говорил о «коротком», а не «int». Знаете ли вы о какой-либо платформе, на которой 'short' не будет работать, но' s8' и 's16' оба будут? Я знаю, что это вполне возможно в теории, но я почти уверен, что большинство библиотек, в которых я вижу типизированные методы, никогда не будут нацелены на такие платформы. – Mehrdad

ответ

78

stdint.h не существовало, когда эти библиотеки разрабатывались. Таким образом, каждая библиотека сделала свои typedef с.

+1

Ну почему же не все просто берут типы из какой-либо другой библиотеки или заголовочного файла? Почему Glib (который был разработан на Linux) не использовал Linux typedefs? – Amomum

+3

И ладно, я полагаю, что отсутствие stdint.h - хорошая причина, но почему даже сегодня эти typedefs превышают int, long и so for, а не по типам stdint? Это сделало бы их взаимозаменяемыми atleast – Amomum

+1

@Amomum Удаление 'quint8' (например) сломало бы существующий код. Для всего, что мы знаем, 'quint8' вполне может быть typedef для стандартного 8-разрядного целого числа без знака' uint8_t'. – Kusalananda

39

Для старых библиотек это необходимо, потому что заголовок, о котором идет речь (stdint.h), не существует.

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

+29

Это просто ужасно, и мне хочется плакать: C – Amomum

+12

Типы 'uintN_t' являются необязательными, но типы' uint_leastN_t' и 'uint_fastN_t' не являются. – Kusalananda

+0

@ Kusalananda, похоже, соответствует моему ответу – Ven

12

stdint.h был стандартизован с 1999 года. Более вероятно, что многие приложения определяют (эффективно псевдонимы) типы для обеспечения частичной независимости от базовой архитектуры машины.

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

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

В том случае, когда требования были гораздо менее стандартными, а машинные архитектуры могут отличаться от 16-разрядных, 18-bit до 36-bit мейнфреймов длины слов это было гораздо более важным. Практика гораздо менее актуальна сейчас в мире, сходящемся на 32-битных встроенных системах ARM. Он по-прежнему вызывает озабоченность у младших микроконтроллеров с картами памяти odd.

+1

Конечно, 'stdint.h' стандартизирован с 1999 года, но как долго он доступен на практике? Люди заставляют свои ноги внедрять и внедрять новые стандарты, и в течение этого длительного переходного периода старые методы по-прежнему являются обязательными. –

+1

Один неприятный gotcha с 'stdint.h' - это даже на платформах, где, например, 'long' и' int32_t' имеют одинаковый размер и представление, нет требования, чтобы отбрасывание 'int32_t *' 'long *' дало указатель, который может надежно получить доступ к 'int32_t'. Я не могу поверить, что авторы Стандарта считали очевидным, что совместимые с макетами типы должны быть совместимы с псевдонимами, но поскольку они не заморачивались, чтобы сказать, что авторы gcc и IIRC clang считают, что язык будет улучшен, игнорируя псевдонимы даже в случаях, когда это очевидно. – supercat

+1

@supercat - это, вероятно, стоит представить как ошибку для комитета C ... потому что это * безвозмездно немой *, мягко говоря, – LThode

3

Таким образом, у вас есть сила typedef char для int.

Один «ужас кодирования» упомянул, что один заголовок компании имел точку, в которой программист хотел логическое значение, а символ был логическим натурным типом для задания, и поэтому написал typedef bool char. Затем позже кто-то нашел целое число наиболее логичным выбором и написал typedef bool int.Результат, возраст до Unicode, был фактически typedef char int.

Довольно много перспективной, передовой совместимости, я думаю.