声明不完整的 C 函数
C function with incomplete declaration
我可以使用 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 , %edx
movl , %esi
movl , %edi
movl [=11=], %eax
call foo
movl 0, %esi
movl 0, %edi
movl [=11=], %eax
call foo
movl [=11=], %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
我承认这段代码不应该存在,但是它是允许的,我想知道它在哪种特殊情况下会有用。
有什么线索吗?
编辑
问题calling-c-functions-with-too-many-arguments没有回答这个问题。它提供了有关如何使用 varadic 的信息,但没有提供不完整声明可能有用的示例。
问题也没有回答问题。它解释了不完整原型和完整原型之间的区别,这不是我的问题。
所以,看来我的问题不够明确,我再举个例子:
假设我真的会利用不完整的声明来使用变量参数而不使用 varadic 方法,所以我将示例写为:
int main(void) {
dummy(1, 2, 3);
dummy(1, 2, 3, 4, 5, 6, 7, 8);
}
根据调用约定,第一个函数将使用CPU寄存器传递参数,而第二个调用将使用堆栈。
现在在我的 dummy
函数中,如何读取这些参数并知道是否使用了堆栈?
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?
你不能。除非你做一些 hardware/compiler 特定的 assembly/pointer 技巧。 C 标准不使用术语 "stack" 和堆栈的用法,如果它存在 and/or 则完全使用以及如何使用,这取决于体系结构和编译器。架构上可能不存在堆栈。要读取函数参数,您必须在函数定义内的参数列表中声明它们。
我可以使用 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 , %edx
movl , %esi
movl , %edi
movl [=11=], %eax
call foo
movl 0, %esi
movl 0, %edi
movl [=11=], %eax
call foo
movl [=11=], %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
我承认这段代码不应该存在,但是它是允许的,我想知道它在哪种特殊情况下会有用。
有什么线索吗?
编辑
问题calling-c-functions-with-too-many-arguments没有回答这个问题。它提供了有关如何使用 varadic 的信息,但没有提供不完整声明可能有用的示例。
问题
所以,看来我的问题不够明确,我再举个例子:
假设我真的会利用不完整的声明来使用变量参数而不使用 varadic 方法,所以我将示例写为:
int main(void) {
dummy(1, 2, 3);
dummy(1, 2, 3, 4, 5, 6, 7, 8);
}
根据调用约定,第一个函数将使用CPU寄存器传递参数,而第二个调用将使用堆栈。
现在在我的 dummy
函数中,如何读取这些参数并知道是否使用了堆栈?
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?
你不能。除非你做一些 hardware/compiler 特定的 assembly/pointer 技巧。 C 标准不使用术语 "stack" 和堆栈的用法,如果它存在 and/or 则完全使用以及如何使用,这取决于体系结构和编译器。架构上可能不存在堆栈。要读取函数参数,您必须在函数定义内的参数列表中声明它们。