0

有人可以向我解释这种行为吗?

static short nDoSomething(const char* pcMsg, ...)
{
  va_list pvArgument;
  long lTest;
  void* pvTest = NULL;

  va_start(pvArgument, pcMsg);

  pvTest = va_arg(pvArgument, void*);
  lTest  = (long) pvTest;

  va_end(pvArgument);
  return 0;
}

如果我像这样在 main 中调用这个函数:

int main(int argc, char* argv[])
 {
   char acTest1[20];
   nDoSomething("TestMessage", 1234567L, acTest1);


  return 0;
}

我以为pvTest的地址会在lTest中,但实际上它包含1234567 ...

这怎么可能?

4

2 回答 2

1

你在这里很幸运。

va_start(pvArgument, pcMsg);

准备va_arg(pvArgument,T)提取下一个变量参数pcMsg,假设它是 type T

之后的下一个参数pcMsg实际上是long int 1234567; 但是您错误地将其提取为 avoid *然后将其转换longlTest. 您很幸运,void *系统上的 a 与 a 大小相同long

(或者也许我的意思是奇怪的不幸

于 2013-07-22T08:33:15.300 回答
1

您的代码包含未定义的行为;该标准要求使用提取va_arg的类型与传递的类型相对应(也许是模 cv-qualifiers):您传递了 a long,并读取了 a void*,因此编译器所做的任何事情都是正确的。

实际上,大多数编译器生成的代码不进行类型检查。如果在您的机器上,long并且void*具有相同的大小(并且机器具有线性寻址),您最终可能会得到您传递的任何long. 如果两者的大小不同,但机器是 little endian,并且您传递的值足够小,那么您最终可能也会得到相同的值。但这根本无法保证。

于 2013-07-22T09:00:09.073 回答