api特定typedef的目的是什么,例如GLsizei GLint GLvoid?
我在c和c ++代码中到处都看到了这一点。基本类型通常使用库前缀/后缀来表示。这背后的原因是什么?这是好习惯吗?我的程序应该自己做类似的事吗?
乍一看似乎使代码的可读性稍差。您必须立即将GLint转换为int,这就是一个简单的例子。
UINT之类的东西对我来说更多,至少这会将unsigned int缩短为四个字母。
答案 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}} - 大小的参数。
为什么你有DWORD
和LPARAM
之类的东西。
它也被用作一种抽象形式。这就是为什么你看到像
这样的typedefWPARAM
因为虽然它现在是typedef int Handle;
,但是图书馆作者保留了以后在轨道上更改为其他任何内容的能力,例如int
或他们认为必要的任何其他类型。
但是客户端代码不需要特别知道它是void *
,因为这正是它当前的情况。客户需要知道的是将其传递给接受int
类型的函数。
Typedef还允许在编译时进行配置。例如。某些库可能具有Handle
类型的实数。它可以用诸如
Real
在编译时,库的用户可以选择设置#ifdef USE_DOUBLE_PREC
typedef double Real;
#else
typedef float Real;
#endif
以获得双精度浮点支持,但重要的是没有库代码需要更改才能工作,因为它已被抽象化。
答案 1 :(得分:2)
在大多数情况下,当一个库定义基本类型时,除了标准中类似命名的类型之外没有保证属性(思考INT
,GLint
,gint
,LPSTR
,u32
,u_int
等),目的是:
基于我最喜欢的原则之一“永远不会将愚蠢的东西归咎于恶意”,你可能会选择#2,但这完全取决于你。
就个人编码这样的API而言,我会抛弃特定于库的类型,并使用正确的自然类型(int
,char *
,uint32_t
等)代替它们。然后,我可以很容易地调整我的代码,而不需要我需要的库,并且代码对于不熟悉库的人来说更具可读性。
答案 2 :(得分:1)
它提供了在一个地方更改typedef的能力,而不是在代码库中搜索和替换,如果需要某种方式来改变底层类型。然而,我发现它比任何东西都更“噪音”,并且在现实生活中很少见到它。
我见过的唯一一个例子就是花车,如果你碰巧在游戏中工作,可能需要让你的游戏移植到Nintendo DS,因为DS本身可以使用定点数字。在这种情况下,你有一个浮点数的特殊typedef,所以它确实是在大多数平台上的浮点数和DS上的特殊定点类的类型。