问题描述
我可以使用 gcc -std = C99 -Wall
来构建没有错误的示例:
I can build this example with no errors with gcc -std=C99 -Wall
:
void dummy() {}
int main(void) {
dummy(1, 2, 3);
dummy(120, 144);
}
反汇编显示该函数确实被调用了两次:
The disassembly shows that the function is indeed called twice:
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
我承认该代码不应该存在,但是它是允许的,我想知道在哪种特殊情况下它会有用.
I admit that this code should not exist, but, it is allowed and I am wondering in which special case it would be useful.
有任何线索吗?
编辑
问题 calling-c-functions-with-too-many-arguments不能回答这个问题.它提供了有关如何使用变量的信息,但未提供示例,其中不完整的声明可能很有用.
The question calling-c-functions-with-too-many-arguments does not answer this question. It gives information about how to use varadic but it does not provide an example in which an incomplete declaration can be useful.
问题 func-vs-funcvoid-in-c99 也没有回答问题.它解释了不完整原型和完整原型之间的区别,这不是我的问题.
The question func-vs-funcvoid-in-c99 also does not answer the question. It explains the difference between incomplete and complete prototype which is not my question.
所以,看来我的问题还不够清楚,我将举另一个例子:
So, it seems my question is not clear enough and I am going to give another example:
让我们想象一下,我真的会利用不完整的声明来使用变量参数而不使用变量方法,因此我将示例编写为:
Let's imagine I would really leverage an incomplete declaration to use variable arguments without using the varadic method so I wrote my example as:
int main(void) {
dummy(1, 2, 3);
dummy(1, 2, 3, 4, 5, 6, 7, 8);
}
根据调用约定,第一个函数将使用CPU寄存器传递参数,而第二个函数将使用堆栈.
Accoding to the calling conventions, the first function will use the CPU registers to pass the parameters while the second call will use the stack.
现在在我的 dummy
函数中,我如何阅读这些争论并知道是否使用了堆栈?
Now in my dummy
function, how can I read these arguements and know whether or not the stack was used?
推荐答案
来自 C11标准6.7.5.3p14 :
void dummy(){}
是一个函数声明符,它是一个函数定义(具有 {}
函数体定义). dummy
函数的标识符列表为空-函数声明内的(
)
大括号内没有任何内容.这意味着该函数不带任何参数.
The void dummy() {}
is a function declarator and it is a function definition (it has the {}
function body definition). The dummy
function has an empty identifier list - there is nothing inside (
)
braces inside the function declaration. That means that the function takes no parameters.
int main(void) {
dummy(1, 2, 3);
dummy(120, 144);
}
使用任何参数调用 dummy
均无效,因为这些参数与函数声明不匹配.这是未定义的行为.
Calling dummy
with any parameters is invalid, because the parameters do not match function declaration. This is undefined behavior.
您不能.除非您执行某些硬件/编译器特定的汇编/指针技巧.C标准不使用术语堆栈",也不使用堆栈的用法(如果存在和/或根本不使用堆栈以及如何使用堆栈),这取决于体系结构和编译器.堆栈可能不存在于体系结构上.要读取函数参数,您必须在函数定义内的参数列表中声明它们.
You cannot. Unless you do some hardware/compiler specific assembly/pointer tricks. C standard does not use a term "stack" and the usage of stack, if it exists and/or is used at all and how it is used, this is architecture and compiler dependent. The stack may not exists on a architecture. To read function arguments you have to declare them in the parameter list inside the function definition.
这篇关于具有不完整声明的C函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!