api特定typedef的目的是什么,例如GLsizei GLint GLvoid?

时间:2010-11-21 08:31:36

标签: c++ c opengl typedef

api特定typedef的目的是什么,例如GLsizei GLint GLvoid?

我在c和c ++代码中到处都看到了这一点。基本类型通常使用库前缀/后缀来表示。这背后的原因是什么?这是好习惯吗?我的程序应该自己做类似的事吗?

乍一看似乎使代码的可读性稍差。您必须立即将GLint转换为int,这就是一个简单的例子。

UINT之类的东西对我来说更多,至少这会将unsigned int缩短为四个字母。

3 个答案:

答案 0 :(得分:3)

这不是关于缩短名称,而是关于可移植性。不同的平台需要以不同的方式输入这些东西。

在Std-C中,long可能是32位或64位,具体取决于您的编译器/目标,因此不能安全地假设它是一定的大小。因此,图书馆作者将根据目标平台的知识输入他自己的类型,保证一定的大小。

E.g。

#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类型1}} - 大小的参数。

为什么你有DWORDLPARAM之类的东西。

它也被用作一种抽象形式。这就是为什么你看到像

这样的typedef
WPARAM

因为虽然它现在是typedef int Handle; ,但是图书馆作者保留了以后在轨道上更改为其他任何内容的能力,例如int或他们认为必要的任何其他类型。

但是客户端代码不需要特别知道它是void *,因为这正是它当前的情况。客户需要知道的是将其传递给接受int类型的函数。

Typedef还允许在编译时进行配置。例如。某些库可能具有Handle类型的实数。它可以用诸如

之类的方式定义
Real

在编译时,库的用户可以选择设置#ifdef USE_DOUBLE_PREC typedef double Real; #else typedef float Real; #endif 以获得双精度浮点支持,但重要的是没有库代码需要更改才能工作,因为它已被抽象化。

答案 1 :(得分:2)

在大多数情况下,当一个库定义基本类型时,除了标准中类似命名的类型之外没有保证属性(思考INTGLintgintLPSTRu32u_int等),目的是:

  1. 要对代码进行“品牌化”,并且对代码库有很多严格的依赖性,因此在没有库的情况下重用代码会很麻烦,或者
  2. 忽略C标准为图书馆的需求提供了适当的类型。
  3. 基于我最喜欢的原则之一“永远不会将愚蠢的东西归咎于恶意”,你可能会选择#2,但这完全取决于你。

    就个人编码这样的API而言,我会抛弃特定于库的类型,并使用正确的自然类型(intchar *uint32_t等)代替它们。然后,我可以很容易地调整我的代码,而不需要我需要的库,并且代码对于不熟悉库的人来说更具可读性。

答案 2 :(得分:1)

它提供了在一个地方更改typedef的能力,而不是在代码库中搜索和替换,如果需要某种方式来改变底层类型。然而,我发现它比任何东西都更“噪音”,并且在现实生活中很少见到它。

我见过的唯一一个例子就是花车,如果你碰巧在游戏中工作,可能需要让你的游戏移植到Nintendo DS,因为DS本身可以使用定点数字。在这种情况下,你有一个浮点数的特殊typedef,所以它确实是在大多数平台上的浮点数和DS上的特殊定点类的类型。