gpt4 book ai didi

声明不完整的 C 函数

转载 作者:太空宇宙 更新时间:2023-11-04 02:21:34 24 4
gpt4 key购买 nike

我可以使用 gcc -std=C99 -Wall 毫无错误地构建这个示例:

void dummy() {}

int main(void) {
dummy(1, 2, 3);
dummy(120, 144);
}

反汇编表明该函数确实被调用了两次:

main:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $15, %edx
movl $14, %esi
movl $12, %edi
movl $0, %eax
call foo
movl $300, %esi
movl $200, %edi
movl $0, %eax
call foo
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc

我承认这段代码不应该存在,但是它是允许的,我想知道它在哪种特殊情况下会有用。

有什么线索吗?

编辑

问题calling-c-functions-with-too-many-arguments不回答这个问题。它提供了有关如何使用 varadic 的信息,但没有提供不完整声明可能有用的示例。

问题func-vs-funcvoid-in-c99也不回答问题。它解释了不完整原型(prototype)和完整原型(prototype)之间的区别,这不是我的问题。

看来我的问题还不够清楚,我再举个例子:

让我们想象一下,我真的会利用一个不完整的声明来使用可变参数而不使用 varadic 方法,所以我将我的示例编写为:

int main(void) {
dummy(1, 2, 3);
dummy(1, 2, 3, 4, 5, 6, 7, 8);
}

根据调用约定,第一个函数将使用 CPU 寄存器传递参数,而第二个调用将使用堆栈。

现在在我的 dummy 函数中,我如何读取这些参数并知道是否使用了堆栈?

最佳答案

来自 C11 standard 6.7.5.3p14 :

An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters.

void dummy() {} 是一个函数声明符,它是一个函数定义(它具有 {} 函数体定义)。 dummy 函数有一个空标识符列表 - ( ) 函数声明内的大括号内没有任何内容。这意味着该函数不带参数。

int main(void) {
dummy(1, 2, 3);
dummy(120, 144);
}

使用任何参数调用dummy 都是无效的,因为参数与函数声明不匹配。这是未定义的行为。

Now in my dummy function, how can I read these arguments and know whether or not the stack was used?

你不能。除非你做了一些硬件/编译器特定的汇编/指针技巧。 C 标准不使用术语“堆栈”和堆栈的用法,如果它存在和/或被使用,以及它是如何使用的,这取决于体系结构和编译器。架构上可能不存在堆栈。要读取函数参数,您必须在函数定义内的参数列表中声明它们。

关于声明不完整的 C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57216969/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com