C++ 是C++;调用约定受标准约束,因为在声明fn时不需要定义函数的返回类型?

C++ 是C++;调用约定受标准约束,因为在声明fn时不需要定义函数的返回类型?,c++,return-value,return-type,C++,Return Value,Return Type,当我在维基百科上学习时,我被以下章节中的例子困住了: 我知道栈的空间需要分配给返回值,但是看到这个例子让我觉得C++调用约定可能决定返回值的栈管理是由定义函数的代码块来处理的,而不是调用它的代码块。因此,我研究了“C对C++调用约定”(回忆栈返回值分配问题可能是主要的区别),并指出,“调用约定”不是由标准定义的。 然而,鉴于上述代码段是有效的这一明显要求,在我看来,调用约定必须有一些约束才能支持上述代码段 我说得对吗?C++标准是否隐含地要求函数定义返回函数的堆栈管理由定义函数的代码来处理,以支

当我在维基百科上学习时,我被以下章节中的例子困住了:

我知道栈的空间需要分配给返回值,但是看到这个例子让我觉得C++调用约定可能决定返回值的栈管理是由定义函数的代码块来处理的,而不是调用它的代码块。因此,我研究了“C对C++调用约定”(回忆栈返回值分配问题可能是主要的区别),并指出,“调用约定”不是由标准定义的。 然而,鉴于上述代码段是有效的这一明显要求,在我看来,调用约定必须有一些约束才能支持上述代码段


我说得对吗?C++标准是否隐含地要求函数定义返回函数的堆栈管理由定义函数的代码来处理,以支持上面的语法?<注释> < >
在编写示例时,结构S和函数f都是前向声明。如果您试图使用其中一种方法,编译器确实会抱怨

**编辑正如Steven Sudit所指出的,函数f不是一个转发声明,而是一个函数原型**


此外,我认为默认调用约定(和可选调用约定)明确地依赖于实现,具有外部链接的除外。如果你搜索C++标准的“调用约定”。第7.5节连杆规格中仅提及一次

至于你的具体问题

我说得对吗?C++标准是否隐含地要求函数的返回值的堆栈管理由定义函数的代码来处理,以支持上面的语法?


当然不是,因为许多编译器支持调用约定,其中值甚至不在堆栈上传递/返回(FASTCALL)或调用方清理堆栈的microsofts版本(thiscall)。

C/C++标准没有定义。这是编译器供应商自己实现的工作,调用约定关键字以下划线开头表明它们是供应商提供的扩展,这一点很明显

C/C++标准定义了基本规则(如何为参数和返回值赋值、按值传递与按引用传递等),但调用约定规定了如何以不同的方式完成这些规则(通过堆栈或寄存器传递参数、顺序、寄存器、谁清理堆栈等)

在x86的情况下,供应商已经就
\uuuuu cdecl
\uuu stdcall
调用互操作性约定的语义达成一致(尽管在某些情况下
\uuuu cdecl
实现中有一些细微的变化),但其他调用约定是特定于供应商的(微软的
\uuuuuFastCall
/
\uuuuThisCall
,博兰德的
\uuuuuFastCall
/
\uuuuuSafeCall
/
\uuuuMSFastCall
,等等)


在x64的情况下,只有一个调用约定,由x64本身决定。调用约定关键字被x64编译器默默忽略,因此现有代码仍将正确编译和工作(只要它不使用内联程序集直接访问/操作调用堆栈).

在编写示例时,结构S和函数f都是前向声明。如果您试图使用它,编译器确实会抱怨-多么明显。我将更新Wikipedia文章中的注释。您不妨将您的注释作为答案发布。谢谢!而且,我相信默认调用约定(和可选的调用约定)是显式实现,依赖于外部链接的例外。如果您搜索C++标准来调用“约定”。在第7.5节链接规范中只提到过一次,即当
s
仍然不完整时,实际定义
f
或调用
f
是不合法的。@Dan Nissenbaum;我在过去一个小时里一直被你的问题历史所吸引。我真的印象深刻。我学到了很多。+1推荐给大家。小nit about您的原始注释:没有函数的“正向”声明,只有声明。带有函数体的声明称为定义。
struct S;     // declaration of S
...
S f();        // ok, no definition required
...