标准 C 函数声明语法 (WINAPI)
The standard C function declaration syntax (WINAPI)
我知道您可能认为这个问题已经得到解答,但事实并非如此,或者至少我不是很清楚。
int WINAPI WinMain (){}
这是著名的 winmain
函数的伪形式。
我的问题是关于调用约定 WINAPI
,特别是它在 "return type" 和 "function name" 之间的位置 。这是标准C吗?因为我参考了 Brian W. Kernighan 和 Dennis M. Ritchie 的书,但我没有看到这个表格。
我也搜索过它的意思,他们说这是一个宏来代替_stdcall
。所以请不要告诉我这个问题是重复的。
这是一个可能与我非常接近的问题
What does "WINAPI" in main function mean?
我想要一个明确的答案WINAPI
:它是标准的 C 语言吗? 所以我可以在 return 类型之后放置一个调用约定函数声明,然后我将它交给世界上的 any C 编译器?或者它是否只适用于 Microsoft 编译器?如果是这样,任何人都可以将他们的规则强加于 C 语法吗?
很抱歉,我知道我的问题对你们中的许多人来说可能微不足道,但我到处搜索函数声明语法,所有来源都拒绝了这个调用约定的地方。
您明确问题的答案:
WINAPI
, Is it a standard C?
不是。__stdcall
是 Microsoft 扩展。
__stdcall
和关键字的位置都是 Microsoft 特定的。任何编译器供应商都能够在其实现中添加非标准语法。
在 this MSDN 文章的最顶部:
Microsoft Specific
它还在页面末尾提到了 WINAPI
宏:
In the following example, use of __stdcall results in all WINAPI function types being handled as a standard call: [...]`
这种形式适用于 Microsoft C++ 编译器和 MinGW 工具链,它为 Windows 实现了 GCC。
但一般来说,GCC 使用它的属性来使用这种其他形式:
int WinMain() __attribute__((stdcall)) // or WINAPI if using the macro
{}
不过,将来我们有可能通过使用最近的 C++11 generalized attributes 比如.
[[ms::stdcall]]
int WinMain() {}
WINAPI
是在 windows.h
中定义的宏,扩展为 __stdcall
。 windows.h
和 __stdcall
都是 Windows 特定的——没有任何行业标准定义它们含义的任何方面。
C 和 C++ 标准确实定义了对函数定义具有相关影响的关键字:inline
、_Noreturn
(C2011) 和 static
。所有这些关键字通常都放在 之前 return 类型,但如果我正确阅读 C2011,语法实际上并不要求这样做:你完全可以写
int static foo(void) { return 42; }
这些关键字称为函数说明符和存储class说明符。
不要将它们与type specifiers和type qualifiers混淆,它们也可以出现在这个位置,但是修改return 当他们这样做时键入。
基本答案:否。C 语言标准定义的函数声明在 return 类型和函数名称之间没有元素。所以 int __bootycall myFunc(int qux)
不是标准 C(或 C++),即使 C 实现允许保留 __customIdentifiers
供自己独占使用。
但是
调用约定说明符(例如 __cdecl
)的需求很明确;许多(尤其是早期的非 UNIX [尤其是 MS-DOS])平台有不止一种调用约定可供选择,并且指定函数的调用约定与参数列表一样重要,甚至更重要那个功能。因此需要在其中插入一些额外的东西。
当时(甚至在 C89 之前),没有为特定于体系结构的函数属性做出规定(大概是因为 C 设计的唯一目的是实现 UNIX 实用程序,不需要任何)。这稍后会在 C99 中得到补救,如果 C99 在那时已经存在,那么 __cdecl
等人很可能。应该是函数属性,而不是随机标识符。但事实上,当需要指定非默认调用约定时,有四个合理的地方可以放置它:return 类型之前,return 类型和函数名称之间,函数名和参数列表的左括号,以及参数列表之后。
我在这里推测,但似乎第二种选择最有意义。请记住,这是 C++ 之前的版本;没有 post-arglist-const
,唯一可以出现在 return 类型之前的是 static
,它指定了链接而不是任何东西 about 函数本身。留在函数名称之前或之后,并将函数名称与其参数列表分开会降低可读性。这在 return 类型和函数名称之间留下了一个稍微不寻常的位置,作为坏一堆中最好的。
剩下的就是历史了。后来的编译器利用新生的 __attribute__
语法将调用约定关键字放在更合适的位置,但是基于 DOS 的编译器(其中 Microsoft C 是第一个)将它推到 return 之后类型。
我知道您可能认为这个问题已经得到解答,但事实并非如此,或者至少我不是很清楚。
int WINAPI WinMain (){}
这是著名的 winmain
函数的伪形式。
我的问题是关于调用约定 WINAPI
,特别是它在 "return type" 和 "function name" 之间的位置 。这是标准C吗?因为我参考了 Brian W. Kernighan 和 Dennis M. Ritchie 的书,但我没有看到这个表格。
我也搜索过它的意思,他们说这是一个宏来代替_stdcall
。所以请不要告诉我这个问题是重复的。
这是一个可能与我非常接近的问题 What does "WINAPI" in main function mean?
我想要一个明确的答案WINAPI
:它是标准的 C 语言吗? 所以我可以在 return 类型之后放置一个调用约定函数声明,然后我将它交给世界上的 any C 编译器?或者它是否只适用于 Microsoft 编译器?如果是这样,任何人都可以将他们的规则强加于 C 语法吗?
很抱歉,我知道我的问题对你们中的许多人来说可能微不足道,但我到处搜索函数声明语法,所有来源都拒绝了这个调用约定的地方。
您明确问题的答案:
WINAPI
, Is it a standard C?
不是。__stdcall
是 Microsoft 扩展。
__stdcall
和关键字的位置都是 Microsoft 特定的。任何编译器供应商都能够在其实现中添加非标准语法。
在 this MSDN 文章的最顶部:
Microsoft Specific
它还在页面末尾提到了 WINAPI
宏:
In the following example, use of __stdcall results in all WINAPI function types being handled as a standard call: [...]`
这种形式适用于 Microsoft C++ 编译器和 MinGW 工具链,它为 Windows 实现了 GCC。
但一般来说,GCC 使用它的属性来使用这种其他形式:
int WinMain() __attribute__((stdcall)) // or WINAPI if using the macro
{}
不过,将来我们有可能通过使用最近的 C++11 generalized attributes 比如.
[[ms::stdcall]]
int WinMain() {}
WINAPI
是在 windows.h
中定义的宏,扩展为 __stdcall
。 windows.h
和 __stdcall
都是 Windows 特定的——没有任何行业标准定义它们含义的任何方面。
C 和 C++ 标准确实定义了对函数定义具有相关影响的关键字:inline
、_Noreturn
(C2011) 和 static
。所有这些关键字通常都放在 之前 return 类型,但如果我正确阅读 C2011,语法实际上并不要求这样做:你完全可以写
int static foo(void) { return 42; }
这些关键字称为函数说明符和存储class说明符。 不要将它们与type specifiers和type qualifiers混淆,它们也可以出现在这个位置,但是修改return 当他们这样做时键入。
基本答案:否。C 语言标准定义的函数声明在 return 类型和函数名称之间没有元素。所以 int __bootycall myFunc(int qux)
不是标准 C(或 C++),即使 C 实现允许保留 __customIdentifiers
供自己独占使用。
但是
调用约定说明符(例如 __cdecl
)的需求很明确;许多(尤其是早期的非 UNIX [尤其是 MS-DOS])平台有不止一种调用约定可供选择,并且指定函数的调用约定与参数列表一样重要,甚至更重要那个功能。因此需要在其中插入一些额外的东西。
当时(甚至在 C89 之前),没有为特定于体系结构的函数属性做出规定(大概是因为 C 设计的唯一目的是实现 UNIX 实用程序,不需要任何)。这稍后会在 C99 中得到补救,如果 C99 在那时已经存在,那么 __cdecl
等人很可能。应该是函数属性,而不是随机标识符。但事实上,当需要指定非默认调用约定时,有四个合理的地方可以放置它:return 类型之前,return 类型和函数名称之间,函数名和参数列表的左括号,以及参数列表之后。
我在这里推测,但似乎第二种选择最有意义。请记住,这是 C++ 之前的版本;没有 post-arglist-const
,唯一可以出现在 return 类型之前的是 static
,它指定了链接而不是任何东西 about 函数本身。留在函数名称之前或之后,并将函数名称与其参数列表分开会降低可读性。这在 return 类型和函数名称之间留下了一个稍微不寻常的位置,作为坏一堆中最好的。
剩下的就是历史了。后来的编译器利用新生的 __attribute__
语法将调用约定关键字放在更合适的位置,但是基于 DOS 的编译器(其中 Microsoft C 是第一个)将它推到 return 之后类型。