有人可以向我解释这种行为吗?
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 ......
这怎么可能?
答案 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*
,所以编译器所做的任何事都是正确的。
实际上,大多数编译器都会生成没有类型的代码
检查。如果您的计算机上long
和void*
具有相同的权限
大小(和机器有线性寻址),你可能会
结束你传递的任何内容long
。如果的大小
两个是不同的,但机器是小端,你
通过一个足够小的值,你可能会得到相同的值
同样。但这根本不能保证。