简体   繁体   English

两次将va_arg传递给一个函数,结果相同

[英]Passing on va_arg twice to a function result in same value

I'm trying to use va_arg to make a generic factory function in my GUI library. 我正在尝试使用va_arg在我的GUI库中创建通用工厂函数。 When passing va_arg twice in the same function they pass on the same value instead of two different: 在同一函数中两次传递va_arg时,它们传递的是相同的值,而不是两个不同的值:

GUIObject* factory(enumGUIType type, GUIObject* parent, ...){
   va_list vl;
   va_start(vl, parent);
   ...
   label->SetPosition(va_arg(vl, int), va_arg(vl, int));
   va_end(vl);
   return finalObjectPointer;
}

factory(LABEL, theParent, 100,200); // Results in position 200:200

What causes this unexpected behavior? 是什么导致这种意外行为?

The compiler is not guaranteed to evaluate arguments in order. 不能保证编译器按顺序评估参数。 Add some additional local variables and do the two assignments in sequence. 添加一些其他局部变量,并依次执行两个分配。

See this other stack overflow posting. 等堆栈溢出张贴。

int v1 = va_arg(vl, int);
int v2 = va_arg(vl, int);

label->SetPosition(v1, v2);

To get what you are observing: the exact same value twice -- probably requires a compiler bug piled on top of the undefined order of evaluation situation, or some entertaining aspect of the particular macro expansion of va_arg in your environment. 要获得您所观察的结果:两次完全相同的值-可能需要在未定义评估情况的顺序之上堆放一个编译器错误,或者在您的环境中va_arg的特定宏扩展具有某些娱乐性。

va_arg is a macro. va_arg是一个宏。 What's hiding behind that macro is implementation defined, which means that it is quite possible that operations performed in place of va_arg have side effects . 该宏背后隐藏的是实现定义,这意味着代替va_arg执行的操作很可能会产生副作用 For this reason, it is not a good idea to use va_arg more than once between two adjacent sequence points. 因此,在两个相邻序列点之间多次使用va_arg并不是一个好主意。 This is potentially undefined behavior, meaning that anything can happen. 这是潜在的不确定行为,意味着任何事情都可能发生。 Looks like this is exactly what happens in your case, which results in this "weird" behavior when you get two identical values from va_arg . 看起来这正是您所遇到的情况,当您从va_arg获得两个相同的值时,将导致此“怪异”行为。

Even if there's no undefined behavior in some implementation, the order of argument evaluation in a function call is unspecified , meaning that using any "sequential readers" in the way you use them is not guaranteed to work as intended (whatever it is you intended). 即使某些实现中没有未定义的行为,函数调用中的参数求值顺序也未指定 ,这意味着按使用它们的方式使用任何“顺序读取器”都不能保证按预期方式工作(无论您打算使用哪种方式) 。

There are no sequence points in between the evaluations of different arguments, so modifying the same value ( vl or something it refers to) twice while evaluating the arguments leads to unspecified behaviour. 在对不同自变量的求值之间没有顺序点,因此在对自变量求值时修改两次相同的值( vl或它所引用的内容)会导致未指定的行为。

va_arg changes the internal state of vl to register which arguments are already handled, and when doing this twice during argument evaluation it is unspecified what happens. va_arg更改vl的内部状态以注册已处理的参数,并且在参数评估期间两次执行此操作时,未指定会发生什么。 Your compiler and the optimizations it uses seem to result in two identical parameters being passed. 您的编译器及其使用的优化似乎导致传递了两个相同的参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM