【问题标题】:Pascal and cdecl keyword in C language [closed]C语言中的Pascal和cdecl关键字[关闭]
【发布时间】:2018-01-08 03:01:15
【问题描述】:

一个面试问题在我脑海中引起了强烈的困惑,即让我们看看这个程序

#include "stdio.h"

int main()
{
    static int a=25;
    void cdecl conv1();
    void pascal conv2();
    conv1(a);
    conv2(a);
    return 0;
}

void cdecl conv1(int a,int b)
{
    printf("%d%d", a, b);
}

void pascal conv2(int a,int b)
{
    printf("\n%d%d", a, b);
}

输出是

25 0

0 25

但是为什么呢?怎么做?

你能简单解释一下吗,因为我不明白 UGC 书中提到的这个程序。

请帮助我更好地理解这个概念,以便我更好地准备面试。

感谢您宝贵的时间。

【问题讨论】:

  • 您的问题不清楚。该程序不是有效的 C OR Pascal。
  • cdeclpascal 不是 C 语言的一部分,而是针对不同调用约定的编译器扩展。显然它们会影响参数传递给函数的方式。但是,当您调用具有错误参数数量的函数时会发生什么并不是很有趣。我真的不想为使用它来筛选申请人的公司工作。
  • 您在 Windows 上使用 Microsoft 编译器?您应该在问题中提及平台和编译器...
  • 您没有传入b 的参数有点奇怪。标准 C 没有“默认参数”支持。你看过 C 和 Pascal 的汇编调用约定吗?每种语言都可以选择如何将参数传递给函数。在将参数压入堆栈时,他们还可以选择将它们压入的顺序(从前到后,而不是从后到前)。特别是,C 将参数从后到先推送到堆栈中,我相信 Pascal 约定是从前到后的。
  • 我已经删除了你的 Pascal 标签。该标签被描述为有关 Pascal 编程语言的问题,而您的问题与 Pascal 语言完全无关。请阅读标签描述而不是仅仅添加它们,因为它们听起来很合适。标签在这里具有特定的含义和相关性。谢谢。

标签: c cdecl


【解决方案1】:

(正如Bo Persson 已经暗示的那样,这(可能)与所谓的调用约定有关。

维基百科x86 calling conventions有一个很好的解释。

简短的总结:不同的语言(分别是编译器)可能有不同的约定,函数参数的传递顺序(例如在堆栈上)。

如果您想链接使用不同语言编写代码的目标文件,这可能会成为一个问题。因此,一些编译器具有扩展来更改函数调用的调用约定。 (当然,如果没有表示使用 native。)


Story Teller 指出(除了调用约定问题之外)您的示例代码中还有其他内容非常可疑。

main 中的原型 conv1()conv2() 具有未指定的参数列表。这在 C 中是允许的(例如在SO: C: Unspecified number of parameters - void foo() 中详细说明)。不幸的是,它阻止了错误调用的检测。

conv1()conv2() 各有 两个 参数。但是,两者都在 main() 中使用 one 参数调用。这是未定义的行为。

(感谢 Story Teller 让我认识到这一点。调用约定让我完全监督这一点以及 Bo Perssons 评论中的提示。)

【讨论】:

  • @StoryTeller 我认为在 C 中,空参数列表意味着函数可以接受任意数量的参数。如果你想声明一个不带参数的函数,你需要使用void?喜欢:void myfunc(void).
  • @NikosC。并不真地。它只是意味着“未指定”(相对于变量/可变参数)。
  • 这看起来像是评论,而不是对 OP 问题的回答。
  • @NikosC。在 C 中,空括号表示函数不是可变参数(在参数列表的末尾没有 , ...),但参数在其他方面未指定——在类型和数量方面。这意味着编译器无法使用声明来检查调用是否正确。
  • @Scheff:可能pascal 是一个调用约定:被调用者清除堆栈,从左到右传递(不像 cdecl,调用者清除堆栈并从右到左传递)。调用约定不一定因语言而异。 Windows 上的大多数语言都知道几种,最重要的是 cdeclstdcallpascal 是一个相当古老的约定,在 Win32 中几乎没有使用过。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-23
  • 1970-01-01
  • 2018-06-19
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
相关资源
最近更新 更多