studies

いろいろ勉強用備忘録的な感じ

無名共用体を見かけた

無名共用体(anonymous union)を久しぶりに見た。

無名共用体というのは、こんなやつ。

#include <iostream>
using namespace std;

static struct {
    char dummy;
    union {
    // これが無名共用体よ
        long data_double_word;
        struct {
        // これは無名構造体だ
        // リトルエンディアンを想定
            short data_word_low;
            short data_word_high;
        };
    };
} foo;

int main() {
    foo.data_word_low = 8;
    foo.data_word_high = 1;
    cout << foo.data_double_word << endl; // 65544 = 1 << 16 + 8
}

しかし、気になったことには、今回見かけたソースは上のようなC++のソースではなく、Cで書かれていた。
Cでanonymous unionとか、anonymous structなんて使えるのか??

Cで書くならこうだろうと思っていた(というか、こういうコードしか見たことがなかった)ので、少し意外な感じ。

#include <stdio.h>

static struct {
    char dummy;
    union {
    /* dataという名前のタグのない共用体 */
        long double_word;
        struct {
        /* wordという名前のタグのない構造体 */
        /* リトルエンディアンを想定 */
            short low;
            short high;
        } word;
    } data;
} foo;

int main(void)
{
    foo.data.word.low = 8;
    foo.data.word.high = 1;

    /* 65544 = 1 << 16 + 8 */
    printf("%ld\n", foo.data.double_word);
}

調べてみると、どうやら、無名共用体も、無名構造体も、C11から使えるようになったらしい。
しかし、C99標準では使えないらしく、可搬性を意識しているソースでは導入が進んでいないようだ。
(もちろん、C11リリース以前に書かれたソースでは、皆無。もしかしたらコンパイラの独自拡張機能としてあったかもしれないけど)。
やはり、今回見かけたCの無名共用体は今のところはまだレアキャラのようです。

www.buildinsider.net
www.kijineko.co.jp