【发布时间】:2013-09-18 13:45:16
【问题描述】:
我正在使用的编译器(ARM 的 Codesourcery)中有一个错误会破坏 va_arg(),我正在尝试解决这个问题。在这种情况下,'ap' 是一个指向 32 位和 64 位参数列表的简单指针。编译器 bug 是 va_arg() 坏了,有时会返回不正确的值。
我可以将 va_list 转换为任意类型的指针,并使用它来提取列表中的值:
void foo(va_list ap)
{
int32_t ival;
double dval;
ival = *(int32_t*)≈
dval = *(double*)&ap);
}
但是,如何将增量“ap”作为强制转换类型预先或后置?
例如,这两个都给出错误:
(int32_t*)&ap++;
++(int32_t*)&ap.
真正的“C”大师能帮我一把吗?我有一个使用联合来操作指针的解决方案,但我想要一个更“c-worthy”的方法......
【问题讨论】:
-
您使用的是哪个版本的编译器?你如何调用它?什么优化标志等等...
-
我希望你的嵌入式产品是一个不重要的小工具(而不是真正有用的东西,比如空调系统),我不会购买或使用它。看到(恕我直言,非常不专业)的行为让我感到害怕“我不介意未定义的行为;它对我有用一次,所以对其他人应该没问题......”
-
其实不会是未定义的。该修复是在编组 va_list 上的参数和从 va_list 中提取值时分析编译器生成的汇编代码的结果。 va_arg() 宏生成的代码错误地计算了地址。因此,如果您知道参数是如何编组的,那么您就知道应该如何检索它们。除非我们更改编译器(并且如果编译器的行为不同),否则不会有问题。 QED。
-
但是几个月后,随着产品的更新,您将稍微更改您的代码和编译器......所以我很害怕(更不用说我我对其余代码的质量没有信心)。
-
我不建议其他人采用此修复程序,顺便说一句。这似乎是一个影响某些 ARM 实现的相对不寻常的问题。而且,我不是真正的程序员,但我在电视上玩过一个......
标签: pointers casting variadic-functions