【问题标题】:Convert Address to long - variable results in value?将地址转换为长变量结果值?
【发布时间】:2013-07-22 07:55:22
【问题描述】:

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

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 ...

这怎么可能?

【问题讨论】:

  • 当你说pvTest的地址时,你的意思是:pvTest指向的地址,对吧?你很困惑为什么那个1234567,对吗?
  • 要获取pvTest的地址,你必须获取它的地址:(long)&pvText

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


【解决方案1】:

您的代码包含未定义的行为;该标准要求 使用va_arg提取的类型对应的类型 通过(可能是模 cv 限定符):您通过了 long,并且 读取void*,所以编译器所做的任何事情都是正确的。

实际上,大多数编译器生成的代码都没有类型 检查。如果在您的机器上,longvoid* 具有相同的 大小(并且机器具有线性寻址),您可能会 以long 传递的任何内容结束。如果尺寸的 两个是不同的,但是机器是小端的,你 传递一个足够小的值,你最终可能会得到相同的值 也是。但这根本无法保证。

【讨论】:

    【解决方案2】:

    你在这里很幸运。

    va_start(pvArgument, pcMsg);
    

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

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

    (或者我的意思是非常不幸

    【讨论】:

      猜你喜欢
      • 2016-11-21
      • 2014-06-27
      • 2010-10-22
      • 1970-01-01
      • 2014-08-05
      • 2012-03-09
      • 2020-07-09
      • 2022-11-02
      相关资源
      最近更新 更多