質問。どうしてそのような質問をしようと思ったのですか?unionのwikipediaのページには一言も未規定、未定義という言葉が出てきていないのですが。「悪魔の証明」という言葉をご存知ですか?無実を証明することは難しいんですよ。
例えば、次のコードは、未定義の動作となりますか?
なりません。
Wikipedia のC言語の欄では、/* これはダメ: 今u2に入っているのはあくまでFoo型 */ との文がありますが。
未定義の動作、ですか?
このwikiページを書いた人はサディストだなあと。
/* u2.bar.pbar = NULL; */ /* これはダメ: 今u2に入っているのはあくまでFoo型 */
というのは、この後、このコードがfooとして使われてるのかbarとして使われてるのかわからないのですよ。だから一概にダメとは言えなくてですね。
C
1char *str = "ABC";
2u2.bar.pbar = (void*)str;
3printf("%f\n", u2.foo.dfoo);
こういうのがイカンのですよ。未定義うんぬん以前の話として、「お前いったい何がしたいん???」って全員から言われますね。または、単なるバグだと。まず、void*はアドレス値を保持しますがそれをdoubleの書式で出力してどないすねん、で、fooとbarの一個目はたまたま同じintだからstructのパディング同じになる「だろう」けど一個目がintとchar[10]だったらどうすんねん。データはぜんぜん違うところ入ってますよ、意味のないデータ拾ってますよ、ってことになります。
そもそもunionをunionだけで使っちゃいけないんですよ。その外側でどうやって使ってるのかがきちんと分かるように管理しなければならない。だからCのコードでunionはあまり見かけないですね。unionを使ったコーディングはよほど分かってる人じゃないと書けない。例えば私はこうやって書いてますね。手前味噌で申し訳ないですけど…。
C
1typedef enum tag_ObjectType {
2 OBJECT_TYPE_INTEGER,
3 OBJECT_TYPE_LIST
4} ObjectType;
5
6struct tag_Object; // オブジェクト型の前方宣言
7
8typedef struct tag_ListObjectComponent {
9 struct tag_Object *car; // carはリストの要素(伝統的な概念)
10 struct tag_Object *cdr; // cdrはリストの後続部(伝統的な概念)
11} ListObjectComponent;
12
13typedef struct tag_Object {
14 ObjectType type;
15 union {
16 int i;
17 ListObjectComponent list;
18 } d;
19} Object;
unionの中身を識別するためにenumを置いてるのですよ。unionを使うにはこれくらいはしないとダメです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/27 03:22
2020/06/27 07:04
2020/06/28 11:14
2020/07/04 03:06