|
1
1
很多“如果”:
然后,函数的激活记录是可预测的(即,您查看生成的程序集并假设它总是相同的):返回地址将在某处,保存的bp(如果您的体系结构有一个基指针),参数的顺序将相同。那么,您如何知道传递了哪些实际参数?您必须对它们进行编码(它们的大小、偏移量),大概在第一个参数中,就像printf所做的那样。 递归(即在递归调用中没有区别)每个实例都有它的激活记录(我说过你必须说服你的编译器永远不会优化尾部调用吗?),但在C中,与Pascal不同,你没有返回到调用者激活记录(即局部变量)的链接,因为没有嵌套的函数声明。访问完整的堆栈(即当前实例之前的所有激活记录)非常乏味,容易出错,并且对那些希望操纵返回地址的恶意代码编写者来说,这是最感兴趣的。 所以,这是一个很大的麻烦和假设,基本上没有什么。 |
|
2
1
是的,您可以直接通过堆栈访问传递的参数。但不,您不能使用旧式函数定义来创建具有可变数量和参数类型的函数。下面的代码显示了如何通过堆栈指针访问参数。它完全依赖于平台,所以我不知道它是否能在你的机器上运行,但你可以理解
偏移量是一个问题,因为它取决于编译器、操作系统以及谁知道还有什么。 对于这个示例,我在调试器中简单地检查了它,但如果它对您非常重要,我认为您可以为您的机器解决方案提供一些“通用”。 |
![]() |
3
0
如果您声明
您可以声明一个接受未指定数量参数的函数,如下所示(例如):
正如你所看到的, 至少 必须指定一个参数。这样,在函数内部,您就可以访问 最后的 指定的参数。 假设您有以下呼叫:
以下是如何实施
正如您所看到的,这里的问题是每个参数的类型和参数总数都是未知的。所以任何打电话给
因此,通常,第一个参数是字符串(
例如,下面是如何实现行为类似于
注:上面的例子是 不 线程安全,仅在此处提供 作为一个例子 ... |
![]() |
MaPo · Linux,设置锁定ICMP_过滤器选项 5 月前 |
![]() |
Doohyeon Won · 内联函数上的奇怪现象?[关闭] 6 月前 |
![]() |
Bobby · 复合字面值总是左值吗? 6 月前 |
![]() |
9-Pin · C: 嵌套结构的堆栈内存分配 6 月前 |