Какова цель API-специфических typedefs, таких как GLsizei GLint GLvoid? - PullRequest
7 голосов
/ 21 ноября 2010

Какова цель специфических для API типов, таких как GLsizei GLint GLvoid?

Я вижу это везде в коде c и c ++.Базовые типы часто печатаются с префиксом / суффиксом библиотеки.В чем причина этого?Это хорошая практика?Должны ли мои программы делать что-то подобное самим?

На первый взгляд кажется, что код немного менее читабелен.Вам нужно потратить мгновение, чтобы перевести GLint в int в вашей голове, и это простой пример.

Что-то вроде UINT делает больше, так как для меня, по крайней мере, это сокращает беззнаковое int на четыре буквы.

Ответы [ 3 ]

3 голосов
/ 21 ноября 2010

Дело не в сокращении имен, а в переносимости. Разные платформы должны будут по-разному определять эти вещи.

В Std-C long может быть 32 или 64 бита, в зависимости от вашего компилятора / цели, поэтому нельзя с уверенностью предположить, что он имеет определенный размер. Таким образом, автор библиотеки будет печатать свой собственный тип, гарантируя определенный размер, со знанием целевой платформы.

* 1006 Е.Г. *

#ifdef _WIN32
typedef __int64 INT64;  // long will not be 64 bit on Windows/VC.
#elif __GNU_C__
typedef long INT64;  // gcc typically uses 64 bit longs.
#elif // ... other platforms ...
...
#endif

И если компиляторы изменят свойства типов в будущих версиях, типы можно редактировать в одном месте.

В прошлом у вас также был типичный случай, когда int мог бы иметь размер 16 или 32 бита, поэтому вы не могли просто использовать необработанный тип int в коде, где вам требовался аргумент размером DWORD. .

Следовательно, почему у вас есть такие вещи, как LPARAM и WPARAM.

Он также используется как форма абстракции. Вот почему вы видите typedefs вроде

typedef int Handle;

Поскольку сейчас это int, автор библиотеки оставляет за собой возможность изменить его позже на дорожку на что-либо другое, например, void * или любой другой тип, который он сочтет необходимым.

Но клиентскому коду не нужно знать, что это конкретно int, так как это именно то, чем он сейчас является. Все, что нужно знать клиенту, - это передать его функциям, принимающим тип Handle.

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

#ifdef USE_DOUBLE_PREC
typedef double Real;
#else
typedef float Real;
#endif

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

2 голосов
/ 21 ноября 2010

По большей части, когда библиотека определяет базовые типы без гарантированных свойств, кроме типов с аналогичными именами в стандарте (например, INT, GLint, gint, LPSTR, u32, u_intи т. д.), целью является либо:

  1. "маркировать" ваш код с большой жесткой зависимостью от библиотеки, поэтому повторно использовать код без библиотеки очень сложно, либо
  2. Незнание того, что стандарт C предоставляет соответствующие типы для нужд библиотеки.

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

Лично при кодировании такого API я выбрасываю специфичные для библиотеки типы и использую правильные натуральные типы (int, char *, uint32_t,и т.д.) на их месте.Тогда мой код легко адаптировать для использования без библиотеки, если мне это когда-либо понадобится, и код будет более читабельным для людей, не знакомых с библиотекой.

1 голос
/ 21 ноября 2010

Это дает возможность изменять typedef в одном месте, а не искать и заменять его по всей базе кода, если возникла необходимость каким-либо образом изменить базовый тип.Тем не менее, я также нахожу это более «шумным», чем что-либо другое, и редко видел, что это когда-либо было необходимо в реальном сценарии.

Единственный пример, который я видел приличное использование - это поплавки, если вы оказалисьдля работы в играх и может потребоваться перенести вашу игру с / на Nintendo DS, поскольку DS изначально работает с числами с фиксированной запятой.В этом случае у вас есть специальный typedef для числа с плавающей точкой, так что он действительно определяется с помощью типа с плавающей точкой на большинстве платформ и специального класса с фиксированной точкой в ​​DS.

...