Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在c中可以用不同的调用约定定义函数吗?_C_Calling Convention - Fatal编程技术网

在c中可以用不同的调用约定定义函数吗?

在c中可以用不同的调用约定定义函数吗?,c,calling-convention,C,Calling Convention,名称后面的mangling将是: int _cdecl f (int x) { return 0; } int _stdcall f (int y) { return 0; } 这并不冲突,这在c中是允许的,如果不是,为什么?首先,这不是损坏,这是装饰。McLink是C++编译器中发生的事情,因为C++最初被设计成支持使用C样式链接工具进行重载。 至于你的问题,你不能有两个同名函数。为了应用该规则,将使用未修饰的名称 为什么会这样?我认为这是因为装饰和调用约定不是C标准的一部分,而是特

名称后面的mangling将是:

int _cdecl    f (int x) { return 0; }
int _stdcall  f (int y) { return 0; }

这并不冲突,这在c中是允许的,如果不是,为什么?

首先,这不是损坏,这是装饰。McLink是C++编译器中发生的事情,因为C++最初被设计成支持使用C样式链接工具进行重载。 至于你的问题,你不能有两个同名函数。为了应用该规则,将使用未修饰的名称


为什么会这样?我认为这是因为装饰和调用约定不是C标准的一部分,而是特定于每个编译器的。我敢肯定,支持多种调用约定的C编译器是在C发明后的几年才出现的。

首先,这不是损坏,而是装饰。McLink是C++编译器中发生的事情,因为C++最初被设计成支持使用C样式链接工具进行重载。 至于你的问题,你不能有两个同名函数。为了应用该规则,将使用未修饰的名称


为什么会这样?我认为这是因为装饰和调用约定不是C标准的一部分,而是特定于每个编译器的。我敢肯定,支持多种调用约定的C编译器是在C发明之后的几年才出现的。

关键字
\u cdecl
\u stdcall
不是C语言的一部分。这些是Microsoft扩展,之前有类似的Borland扩展

在标准C语言中,不能声明调用约定。显然,声明的每个函数都相当于MS编译器所称的“
\u cdecl
”约定


调用这两个函数时,可以使用内嵌汇编来区分这两个函数。因为您使用的是特定于平台的供应商扩展C,您可能会考虑使用联机汇编。

< P>关键字>代码>这些是Microsoft扩展,之前有类似的Borland扩展

在标准C语言中,不能声明调用约定。显然,声明的每个函数都相当于MS编译器所称的“
\u cdecl
”约定


调用这两个函数时,可以使用内嵌汇编来区分这两个函数。因为您使用的是特定于平台的供应商扩展C,您可能会考虑使用联机汇编。

@ HeaSi我不知道标准C指定的调用约定,甚至不知道CDDEL。我错了吗?@David——C标准指定了变量参数,对于基于堆栈的实现,通常通过从右到左的参数传递来完成。此外,在C语言中,调用方必须清除参数,因为调用方可能提供无关的(即太多)参数。这是MS命名为“_cdecl”的约定。另一种选择是_stdcall,Borland称之为“Pascal约定”,将参数从左向右推。被调用者清理堆栈,变量参数是不可能的。@David——当然,我回答的第一句话清楚地表明_cdecl根本不是C的一部分。我的意思是_cdecl是x86上C调用约定的MS名称,因为它基本上由所有x86c编译器实现。如果MS将其编译器移植到另一个ABI上,_cdecl无疑将继续引用平台原生C调用约定。@Heath C标准确实要求能够传递可变数量的参数。但它是否指定了调用约定所需的全部内容?我仍然持怀疑态度,但准备被证明是错误的@David-不,当然它没有为平台指定C ABI。我有说过吗?我想说的是,从定义上讲,“u cdecl”是该平台通常的C-ABI约定——这只是因为微软对它的定义。MS已经将此关键字移植到许多非x86平台(MIPS、SPARC、DEC Alpha、ARM、M68000等),并且在cdecl的含义上保持一致。特别是,_cdecl支持var args和调用者清理,_stdcall不支持。这就是它们的定义,据@Heath女士说,我不知道标准C规定了调用约定,甚至cdecl也没有。我错了吗?@David——C标准指定了变量参数,对于基于堆栈的实现,通常通过从右到左的参数传递来完成。此外,在C语言中,调用方必须清除参数,因为调用方可能提供无关的(即太多)参数。这是MS命名为“_cdecl”的约定。另一种选择是_stdcall,Borland称之为“Pascal约定”,将参数从左向右推。被调用者清理堆栈,变量参数是不可能的。@David——当然,我回答的第一句话清楚地表明_cdecl根本不是C的一部分。我的意思是_cdecl是x86上C调用约定的MS名称,因为它基本上由所有x86c编译器实现。如果MS将其编译器移植到另一个ABI上,_cdecl无疑将继续引用平台原生C调用约定。@Heath C标准确实要求能够传递可变数量的参数。但它是否指定了调用约定所需的全部内容?我仍然持怀疑态度,但准备被证明是错误的@David-不,当然它没有为平台指定C ABI。我有说过吗?我想说的是,从定义上讲,“u cdecl”是该平台通常的C-ABI约定——这只是因为微软对它的定义。MS已经将此关键字移植到许多非x86平台(MIPS、SPARC、DEC Alpha、ARM、M68000等),并且在cdecl的含义上保持一致。特别是,_cdecl支持var args和调用方清理,_stdca
_f
_f@4