不应将非 POD 对象传入可变参数列表
10.6.5 ID_nonPODVariadicArgument
如果将非“POD 类型”的对象传入可变参数列表,程序的行为在 C++03 中是未定义的,在 C++11 中是部分由实现定义的。
示例:
using namespace std;
void foo(int n, ...) {
va_list ap;
....
string s = va_arg(ap, string); // Undefined behavior
....
}
void bar(string& s) {
foo(1, s); // Non-compliant
}
例中 string 类对象不是 POD 对象,其拷贝构造和析构过程难以与可变参数列表机制兼容,通过 va_arg 难以获取正确的对象。
又如:
struct A {
string s;
operator const char*() const {
return s.c_str();
}
};
void foo(const A& a) {
printf("%s\n", a); // Non-compliant
}
即使对象有转为 const char* 的方法,在可变参数列表中也是无效的,printf 无法正确获取字符串地址,造成内存访问错误。
应改为:
void foo(const A& a) {
printf("%s\n", static_cast<const char*>(a)); // Compliant
}
相关
依据
ISO/IEC 14882:2003 5.2.2(7)-undefined
ISO/IEC 14882:2011 5.2.2(7)-implementation