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

C++ 标准C函数声明语法(WINAPI),c++,c,standards,C++,C,Standards,我知道你可能认为这个问题已经得到了回答,但事实并非如此,或者至少我并不十分清楚 int WINAPI WinMain (){} 这是著名的winmain函数的伪形式 我的问题是关于调用约定WINAPI,特别是它在“返回类型”和“函数名”之间的位置。这是标准C吗?因为我引用了Brian W.Kernighan和Dennis M.Ritchie的书,我没有看到这个表格 我还搜索了它的含义,他们说这是一个宏,用来放置\u stdcall。所以请不要告诉我这个问题是重复的 这是一个可能与我非常接近的问

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

int WINAPI WinMain (){}
这是著名的
winmain
函数的伪形式

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

我还搜索了它的含义,他们说这是一个宏,用来放置
\u stdcall
。所以请不要告诉我这个问题是重复的

这是一个可能与我非常接近的问题

我想对这个
WINAPI
是标准C吗?这样我就可以在任何函数声明中的返回类型之后放置一个调用约定,然后将它交给世界上任何C编译器?或者它是只在Microsoft编译器上工作的东西?如果是这样的话,有人能把他们的规则强加给C语法吗


很抱歉,我知道我的问题对你们中的许多人来说可能微不足道,但我到处都在搜索函数声明语法,所有来源都拒绝了这个调用约定的位置。

您明确问题的答案是:

WINAPI
,它是标准的C语言吗


是否。
\uu stdcall
是Microsoft的扩展。

关键字的位置和
\uu stdcall
都是Microsoft特有的。任何编译器供应商都可以向其实现中添加非标准语法

在MSDN文章的最顶端:

特定于Microsoft的

它还提到了页面末尾的
WINAPI
宏:

在下面的示例中,使用uu stdcall将导致所有WINAPI函数类型作为标准调用处理:[……]`

此表单在微软C++编译器和明文工具链上都有作用,它实现了Windows的GCC。 但一般来说,GCC使用其属性使用另一种形式:

int WinMain() __attribute__((stdcall)) // or WINAPI if using the macro
{}
但是,将来我们可能会通过使用最新的语法(例如,
stdcall
部分仍然是特定于平台的),使用更标准的语法(即
stdcall
部分)


事实上,两者都支持标准通用属性,作为编译器特定属性语法的一种替代方法。

WINAPI
是在
windows.h
中定义的宏,它扩展到
\uu stdcall
windows.h
\uu stdcall
都是特定于windows的,没有任何行业标准定义其含义的任何方面

< > C和C++标准定义了对函数定义有相关影响的关键字:<代码>内联,<代码>所有这些关键字通常都放在返回类型之前,但是如果我正确地阅读了C2011,那么语法实际上并不需要这样做:您完全可以编写

int static foo(void) { return 42; }
这些关键字称为函数说明符和存储类说明符。
不要将它们与类型说明符和类型限定符混淆,它们也可以出现在这个位置,但在它们出现时修改返回类型。

基本答案:否。C语言标准定义的函数声明在返回类型和函数名之间没有任何元素。因此,
int\uu bootycall myFunc(intqux)
不是标准的C(或C++),即使C实现允许保留
\uu自定义标识符
供其自己专用

不过

调用约定说明符(例如,
\uu cdecl
)的需求是明确的;许多(特别是早期的非UNIX[特别是MS-DOS])平台有多个调用约定可供选择,指定函数的调用约定与该函数的参数列表同等重要(如果不是更重要的话)。因此,需要在其中插入一些额外的内容

当时(甚至在C89之前),还没有为特定于体系结构的功能属性做任何规定(可能是因为C,专为实现UNIX实用程序而设计,不需要任何功能属性)。这将在C99中得到修正,如果C99当时已经存在,则很可能是函数属性,而不是随机标识符。但事实上,当需要指定非默认调用约定时,有四个合理的位置可以放置它:在返回类型之前,在返回类型和函数名之间,在函数名和参数列表的左括号之间,以及在参数列表之后

我在这里猜测,但第二种选择似乎最有意义。这是C++之前的版本,记住;没有post arglist-
const
,在返回类型之前唯一可以显示的是
static
,它指定了链接,而不是函数本身的任何内容。保留在函数名之前或之后,并将函数名与其参数列表分离会降低可读性。这使得返回类型和函数名之间的位置有点不寻常,这是一堆糟糕的东西中最好的


剩下的就是历史了。后来的编译器利用了新出现的
\uuuuu属性\uuuuuu
语法,将调用约定关键字放在了一个更合适的位置,但是基于DOS的编译器(微软C是其中的第一个)将其推到了返回类型之后。

WINAPI
确实是
\uu stdcall
的同义词,并且在开始时使用
\uuu
的所有内容都是特定于编译器的。Stdcall在MS之外也是一种已知的调用约定,但如何为函数设置它则是另一回事。顺便说一句,您的WinMain缺少参数。@big.heart Yep,在GCC上(不是MinGW,MinGW接受Microsoft sp
int static foo(void) { return 42; }