标准 C 函数声明语法 (WINAPI)

the*_*ant 2 c c++ standards

我知道你可能认为这个问题已经得到了回答,但事实并非如此,或者至少对我来说不是很清楚。

int WINAPI WinMain (){}
Run Code Online (Sandbox Code Playgroud)

这是著名winmain函数的伪形式。

我的问题是关于调用约定WINAPI特别是它在“返回类型”和“函数名称”之间的位置。这是标准C吗?因为我参考了 Brian W. Kernighan 和 Dennis M. Ritchie 的书,但我没有看到这个表格。

我也搜索过它的含义,他们说这是一个可以放置的宏_stdcall。所以请不要告诉我这个问题是重复的。

这是可能非常接近我的问题 之一主函数中的“WINAPI”是什么意思?

我想要一个明确的答案WINAPI它是标准 C 吗?所以我可以在任何函数声明中的返回类型之后放置一个调用约定,然后我将它提供给世界上的任何C 编译器?或者它是否只适用于 Microsoft 编译器?如果是这样,任何人都可以将他们的规则强加于 C 语法吗?

对不起,我知道我的问题对你们中的许多人来说可能是微不足道的,但我到处搜索函数声明语法,所有来源都否认了这个调用约定的地方。

Sne*_*tel 5

基本答案:不。C 语言标准定义的函数声明在返回类型和函数名称之间没有任何元素。所以int __bootycall myFunc(int qux)不是标准的 C(或 C++),即使 C 实现被允许保留__customIdentifiers给他们自己的独占使用。

然而。

调用约定说明符(例如__cdecl)的需求是明确的;许多(尤其是早期的非 UNIX [尤其是 MS-DOS])平台有不止一种调用约定可供选择,并且指定函数的调用约定与指定函数的参数列表一样重要,如果不是更重要的话那个功能。因此需要在那里插入一些额外的东西。

当时(甚至在 C89 之前),还没有为特定于体系结构的功能属性做出规定(大概是因为专为实现 UNIX 实用程序而设计的 C 不需要任何属性)。这稍后会在 C99 中得到补救,如果当时 C99 已经存在,那么很可能是__cdecl等人。本来是函数属性,而不是塞进那里的随机标识符。但事实上,当需要指定非默认调用约定时,有四个合理的地方可以放置它:在返回类型之前,在返回类型和函数名之间,在函数名和函数的左括号之间参数列表,在参数列表之后。

我在这里推测,但似乎第二个选项最有意义。这是 C++ 之前的版本,记住;没有 post-arglist- const,唯一可以出现在返回类型之前的是static,它指定了链接而不是关于函数本身的任何内容。在函数名之前或之后留下,并将函数名与其参数列表分开会降低可读性。这使得返回类型和函数名称之间的稍微不寻常的位置成为最好的一堆。

剩下的就是历史了。后来的编译器利用新生的__attribute__语法将调用约定关键字放在更合适的位置,但是基于 DOS 的编译器(其中 Microsoft C 是最早的编译器之一)将它放在返回类型之后。