6.7.2.1項14これは労働組合とポインタについて言いたいことがある(いつものように強調し、追加):va_argを共用体で使用できますか?
The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit- field, then to the unit in which it resides), and vice versa.
すべてが順調といい、それはそれはに合法であることを意味しこれは言ってい
union ints { int i; unsigned u; };
int i = 4;
union ints is = *(union ints *)&i;
int j = is.i; // legal
unsigned k = is.u; // not so much
7.15.1.1項2:
私たちは、同じタイプのデータにそれをコピーしたいと仮定すると、労働組合に署名またはunsigned int型のいずれかをコピーするには、次のような何かをThe
va_arg
macro expands to an expression that has the specified type and the value of the next argument in the call. The parameterap
shall have been initialized by theva_start
orva_copy
macro (without an intervening invocation of theva_end
macro for the sameap). Each invocation of theva_arg
macro modifiesap
so that the values of successive arguments are returned in turn. The parametertype
shall be a type name specified such that the type of a pointer to an object that has the specified type can be obtained simply by postfixing a*
totype
. If there is no actual next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined, except for the following cases:—one type is a signed integer type, the other type is the corresponding unsigned integer type, and the value is representable in both types;
—one type is pointer to void and the other is a pointer to a character type.
私は、デフォルトの引数のプロモーションについてこの部分を引用するつもりはありません。私の質問は次のとおりです。
void func(int i, ...)
{
va_list arg;
va_start(arg, i);
union ints is = va_arg(arg, union ints);
va_end(arg);
}
int main(void)
{
func(0, 1);
return 0;
}
もしそうなら、克服する巧妙なトリックであるように思われる「とし、値が型の両方と互換性があります」(中とはいえ署名/符号なし整数変換の要件:この定義された動作です法的に何かをするのはむしろ難しい方法です)。そうでない場合は、この場合はunsigned
を使用するだけで安全ですが、より互換性のないタイプの要素が多い場合はどうなりますか?私たちが要素ごとにユニオンにアクセスしないことを保証できれば(すなわち、別のunion
またはそれと同じ扱いのストレージスペースにコピーするだけです)、ユニオンのすべての要素が同じサイズであればvarargsと?またはポインタでのみ許可されますか?
実際には、このコードはほとんど決して失敗しないだろうと期待していますが、定義済みの動作かどうかを知りたいと思います。私の現在の推測は、それは定義されていないようだが、それは信じられないほどばかげているようだ。
私はそれについて考えました。私は、func(0、-1); func(0、UINT_MAX); 'は合法です。 '1 'は' int'と 'unsigned'の両方に収まるので、' func(0、1) 'は正当なものです。 –
'unsigned k = is.u;'はC99では合法です。 –
@Dietrich - 署名付き/署名なしのもののため例外がありますか? –