将地址转换为长变量值的结果?

时间:2013-07-22 07:55:23

标签: c++ casting void-pointers variadic-functions

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

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;
}

如果我像这样在主体中调用此函数:

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


  return 0;
}

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

这怎么可能?

2 个答案:

答案 0 :(得分:1)

你在这里很幸运。

va_start(pvArgument, pcMsg);

准备va_arg(pvArgument,T)以提取下一个变量 pcMsg之后的参数,假设它是T类型。

pcMsg之后的下一个论点实际上是long int 1234567;但 您错误地将其提取为void *,然后将其转换为long lTest。您很幸运,系统上的void *就是 与long相同的大小。

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

答案 1 :(得分:1)

您的代码包含未定义的行为;标准要求 使用va_arg提取的类型对应于类型 传递(modulo cv-qualifiers,也许):你传递了long,和 读一个void*,所以编译器所做的任何事都是正确的。

实际上,大多数编译器都会生成没有类型的代码 检查。如果您的计算机上longvoid*具有相同的权限 大小(和机器有线性寻址),你可能会 结束你传递的任何内容long。如果的大小 两个是不同的,但机器是小端,你 通过一个足够小的值,你可能会得到相同的值 同样。但这根本不能保证。