C++ C++;:将va_列表类型用作类成员是否安全?
将va_列表类型用作类成员是否安全 下面的示例适用于Solaris。它不需要跨不同的操作系统进行移植。但它是否可移植到未来的Solaris版本?不同的硬件?不同的编译器?还是编译器选项C++ C++;:将va_列表类型用作类成员是否安全?,c++,variadic-functions,C++,Variadic Functions,将va_列表类型用作类成员是否安全 下面的示例适用于Solaris。它不需要跨不同的操作系统进行移植。但它是否可移植到未来的Solaris版本?不同的硬件?不同的编译器?还是编译器选项 class MyFormatString { public: MyFormatString(const char* formatString, va_list varg); ~MyFormatString() { va_end(mVarg); } // ... // pr
class MyFormatString
{
public:
MyFormatString(const char* formatString, va_list varg);
~MyFormatString() { va_end(mVarg); }
// ...
// provide some util functions to operate on the format string
// ...
private:
string mFormatString;
va_list mVarg;
};
MyFormatString::MyFormatString(const char* fmt, va_list varg)
{
if (fmt)
mFormatString=fmt;
va_copy(mVarg, varg);
}
这在任何平台上都不安全
va_list
指向当构造函数返回时将过时的堆栈参数。考虑使用更多的C++ -ISH类型安全方法来存储参数;可能存储在std::vector
中,只要在相应的变量函数返回之前销毁所有MyFormatString
实例,这可能会按预期工作
然而,根据C标准,它仍然是未定义的行为,因为在调用va\u copy()
的函数返回之前需要调用va\u end()
,尽管我不知道有哪种实现不足以调用va\u end()
在变量列表
超出范围或相应的变量函数返回之前
如果您正在寻找符合标准的解决方案,请使用va_列表*
,而不是列表的副本。但是,这将在从相同的va_列表创建的MyFormatString
实例之间共享状态,因此它实际上并不等效
如果不想共享状态,则需要手动创建va_列表的副本
,并将指向该列表的指针传递给构造函数
使用“代码> VAYLISTA//CODE >的平台上的指针是一种数组类型,可以用C++引用来避免(显然C标准中没有说明,但应该根据指针语义来进行操作)。
< P>不,只能使用<代码> VAYLISTU/<代码>,而它所指的对象在范围内。(在函数本身中,或作为参数传递给其他函数),直到调用va_end
为止。在从函数返回之前,必须调用va_end
,在该点之后,va_列表不再可用
来自C99,7.15.1.3:“如果在
返回,行为未定义。“
在C++ 11中,考虑变量模板或<代码> STD::tuple < /C> >作为旧式函数的类型安全替代。< / P> OK,我确信它是这样工作的。它甚至可以在不同OS和编译器上进行移植吗?我的答案是错误的,迈克的正确性:<代码> vAuthEnter()
必须在调用va_copy()的相同函数中调用
我还阅读了标准C99,7.15.1.3中提到的部分。我想在Solaris中,这种未定义的行为恰好是,这似乎确实有效。我想一种安全的方法是在成员函数中传递va_list*-type并使用va_copy-va_end?或者将va_列表传递给每个成员函数。。。