yohhoyの日記

技術的メモをしていきたい日記

可変引数リストと非PODクラス型の関係

プログラミング言語C++において、可変引数リスト(...; ellipsis)をとる関数に非PODクラス型を渡した場合の振る舞いについてメモ。

void foo(int, ...);

std::string s;
foo(1, s);  // ??

C++03

可変引数リストに非PODクラス型を渡した場合、未定義動作(undefined behavior)となる。C++03 5.2.2/7より一部引用。

When there is no parameter for a given argument, the argument is passed in such a way that the receiving function can obtain the value of the argument by invoking va_arg (18.7) (snip) If the argument has a non-POD class type (clause 9), the behavior is undefined. (snip)

C++11

可変引数リストに非自明なコピー/ムーブコンストラクタまたは非自明なデストラクタをもつクラス型を渡した場合、処理系によってはサポートされ(conditionally-supported)、そのセマンティクスは処理系定義(implementation-defined)となる。N3337 1.3.5, 5.2.2/7より一部引用。

conditionally-supported
program construct that an implementation is not required to support [Note: Each implementation documents all conditionally-supported constructs that it does not support. -- end note]

When there is no parameter for a given argument, the argument is passed in such a way that the receiving function can obtain the value of the argument by invoking va_arg (18.10). (snip) Passing a potentially-evaluated argument of class type (Clause 9) having a non-trivial copy constructor, a non-trivial move constructor, or a non-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics. (snip)

gcc 4.5.4, 4.6.3, 4.7.1では単に未サポート。

Whether an argument of class type with a non-trivial copy constructor or destructor can be passed to ... (C++0x 5.2.2).
 Such argument passing is not supported.

関連URL