Чому всі набирають тип порівняно зі стандартними типами С?


103

Якщо ви хочете використовувати Qt , ви повинні прийняти quint8, quint16і так далі.

Якщо ви хочете використовувати GLib , ви повинні вітати guint8, guint16і так далі.

У Linux є u32, s16і так далі.

УНЦ / OS визначає SINT32, UINT16і так далі.

І якщо вам доведеться використовувати якесь поєднання цих речей, то краще будьте готові до неприємностей. Тому що на вашій машині u32буде typedefd над longі quint32буде typedefd над intі компілятор буде скаржитися .

Чому всі це роблять, якщо є <stdint.h>? Це якась традиція для бібліотек?


8
@Mehrdad в програмуванні мікроконтролерів ви можете мати всілякі речі. Наприклад, у AVR Mega's (і, отже, на відомому Arduino), int становить 16 біт. Це може бути неприємним сюрпризом. На мою думку, "непідписаний короткий" вимагає більше зусиль для введення тексту. І мені завжди стало сумно, використовуючи "неподписаний знак" для <s> байт </s> октет. Непідписаний персонаж, справді?
Amomum

2
@Mehrdad Справа в тому, що ти справді не можеш бути впевнений. Саме тому stdint.hбуло винайдено.
glglgl

1
@glglgl: Ось ще один спосіб розглянути проблему: чи не задаєте ви саме неправильне запитання? Якщо ви орієнтовані на декілька систем, то чому б довільно жорстко вводити в першу чергу кількість бітів у код? тобто чому б просто не сказати sizeof(int) * CHAR_BIT(наприклад) і використовувати це? Якщо ваш intзанадто малий, щоб представляти діапазон (наприклад, індекс масиву), то ви майже напевно не повинні використовувати intвсе одно, а щось подібне size_t. Чому б це мало int32більше сенсу? Єдиний фіксований по ширині час має сенс для зв'язку між системами (наприклад, формат файлу / мережі) ...
user541686

1
@Mehrdad Ні. Іноді у мене є значення (наприклад, від АЦП або будь-якого іншого), які мені потрібно зберігати. Я знаю, що вони шириною 16 біт. Тож найкращим тингом є uint16_t(або, можливо, його fastчи leastваріант). Моя думка: ці типи зручні у використанні та мають свою причину існування.
glglgl

1
@Mehrdad: Я б запропонував - якщо припустити, що варто зробити ваші зусилля, щоб створити якісний код - вам слід визначити свій власний функціональний typedefs, що означає спосіб взаємодії з моїм API / рештою мого коду , і визначити їх на технічних підставах з точки зору "Технічні" типи типів, такі як size_tта / або uint64_t.
PJTraill

Відповіді:


80

stdint.hне існувало тоді, коли ці бібліотеки розроблялися. Тож кожна бібліотека зробила власні typedefс.


4
І гаразд, я вважаю, що відсутність stdint.h є вагомою причиною, але чому навіть сьогодні ці typedefs є над int, long і так для, а не над типом stdint? Це зробило б їх взаємозамінними якнайменше
Amomum

25
@Amomum "Чому Glib (розроблений на Linux) не використовував Linux typedefs?" Хоча "домашня база" glib, безумовно, є Linux, це, безумовно, за допомогою дизайну портативної бібліотеки. Визначення власних типів забезпечує переносимість: потрібно лише адаптувати крихітний заголовок, який відповідає типам бібліотеки до відповідних відповідних типів платформи.
Пітер - Відновіть Моніку

3
@Amomum Чому Glib (це було розроблено на Linux) ... Ні, це не було. Glib був створений шляхом до ядра Linux.
andy256

5
@ andy256 "GLib" не є скороченням для "glibc". Це бібліотека, що розгалужується від gtk. Це не старше Linux.

2
@ andy256: glib - 1998, Linux - 1991. IOW, GLib був створений після Linux.
MSalters

40

Для старих бібліотек це потрібно, оскільки заголовок, про який йдеться ( stdint.h), не існував.

Однак все ще існує проблема: ці типи ( uint64_tта інші) є необов'язковою характеристикою у стандарті. Тож відповідна реалізація може не поставлятися з ними - і, таким чином, змушує бібліотеки все ще включати їх у наш час.


14
Ці uintN_tтипи НЕ є обов'язковими, але uint_leastN_tі uint_fastN_tтипи не є.
Кусалаланда

7
@Kusalananda: На жаль, вони мають обмежену корисність.
Гонки легкості по орбіті

16
Звичайно, тому , що вони НЕ є обов'язковими, що ви не гарантується , що є ціле число типів з точно такою кількістю бітів. C все ще підтримує архітектури з досить непарними цілими розмірами.
celtschk

5
@LightnessRacesinOrbit: Наскільки вони обмежені? Я мушу визнати, що крім апаратних інтерфейсів, я не бачу, для чого вам знадобиться точна кількість бітів, а не лише мінімум, щоб забезпечити
вміст

23
У @Amomum визначення типів є потрібна , якщо реалізація має тип , що відповідають вимоги: «Тим НЕ менше, якщо реалізація забезпечує ціле число типів з шириною від 8, 16, 32 або 64 біта, без заповнення біт, і (для підписаних типів) , які має представлення доповнення двох, воно повинно визначати відповідні назви typedef. " (цитата з N1570, 7.20.1.1 "Цілі цілі типи ширини") Отже, якщо стандартна бібліотека їх не має, стороння бібліотека також не могла, здається.
Ерік М Шмідт

13

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

Вони надають розробникам впевненість у тому, що типи, які використовуються у їх застосуванні, відповідають конкретним припущенням щодо поведінки проекту, які не можуть відповідати ні мовному стандарту, ні компілятору.

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

Коли компілятори були набагато менш стандартними, а архітектури машин могли змінюватись від 16-розрядних, 18-бітних до 36-розрядних мейнфреймів слів, це було набагато більше уваги. Практика набагато менш актуальна зараз у світі, який конвергується на 32-бітних вбудованих системах ARM. Залишається турбота про мікроконтролери низького класу з непарними картами пам'яті.


1
Звичайно, stdint.hце стандартизовано з 1999 року, але як довго він доступний на практиці? Люди тягнуть ноги, впроваджуючи та приймаючи нові стандарти, і в цей довгий перехідний період старі методи все ще є обов'язковими.
Сіюань Рен

1
Один неприємний глюк з в stdint.hтому , що навіть на платформах , де , наприклад , longі int32_tмають той же розмір і уявлення, немає вимоги , що приведення int32_t*до long*дасть покажчик , який може надійно отримати доступ до int32_t. Я не можу повірити, що автори стандарту вважали очевидним, що типи, сумісні з компонуванням, повинні бути сумісні з псевдонімом, але оскільки вони не турбуються, говорячи, тож автори gcc та IIRC кланг вважають, що мова буде покращена, ігноруючи псевдонім навіть у випадках, коли це очевидно.
supercat

2
@supercat - це, ймовірно , варто подала заявку як помилка в комітет C ... тому що це безпричинно німий , м'яко кажучи
LThode

@LThode: Комітет C визнає, що як помилка вимагає, щоб він офіційно оголосив поведінку clang та gcc як тупу. Ви думаєте, що це станеться? Найкраще, на що можна сподіватись (а IMHO - логічний спосіб протікати) - це визначити шляхи для програм, що визначають "режими згладжування". Якщо програма говорить, що вказує, що вона може приймати дуже суворі правила псевдонімування, тоді компілятор може використовувати це, щоб дозволити оптимізацію за межі того, що зараз можливо. Якщо програма вказує, що їй потрібні правила, дещо приємніші для програмістів, ніж теперішні ...
supercat

... але все-таки дозволять зробити багато корисних оптимізацій, тоді компілятор міг би генерувати код, який був набагато ефективнішим, ніж це було б можливо -fno-strict-alias, але який би насправді працював. Навіть якщо не існувало кодової бази, жоден набір правил не міг би досягти оптимального балансу оптимізації та семантики для всіх застосувань, оскільки різні програми мають різні потреби. Додайте в існуючу базу коду, і необхідність у різних режимах повинна бути зрозумілою.
supercat

3

Таким чином, у вас є сила ввести charde в int.

Один з "кодуючих ужасів" зазначав, що в заголовку однієї компанії була точка, в якій програміст хотів отримати булеве значення, а char - логічний нативний тип роботи, і так написав typedef bool char. Потім хтось знайшов ціле число як найбільш логічний вибір, і написав typedef bool int. Результат, віки до Unicode, був практично typedef char int.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.