LoginSignup
3
4

More than 5 years have passed since last update.

古いC言語(C89/C90)での変数宣言

Posted at

きっかけ

業務として初めてC89(C90)のC言語環境に飛び込むことになった。(組み込み関係)
良く知らない環境なのでお勉強しようと思った。
とはいえ大体は参考のリンク先で分かるので、その他気が付いたことを書く。

参考

旧時代のC言語を使うのはそろそろやめよう。 - Qiita

C言語の最新事情を知る: C99の仕様 - Build Insider

Diagnostic flags in Clang — Clang 6 documentation
↑記事を書いてから気が付いたけど、コンパイラが言語規格に準拠している前提であれば警告を見れば規格のエッセンスが分かりそうだ。

動作確認環境

環境はWandbox使ってみた: [Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

※この記事では、clang5.0.0使ってOptimizationにチェックして-std=c89にして-Weverything付けた環境で見てみた
設定例:https://wandbox.org/permlink/IauhP7p8oMNB6kFy

変数の宣言時初期化

変数宣言はスコープの先頭だけでしょ、宣言は処理の前に書かないとダメなんでしょ。知ってる知ってる。
と思っていたけど、変数宣言時の初期化であれば関数呼び出しも書ける。
ということはC89であっても下記のリファクタリングができる。

before

C89
#include <stdio.h>

static int func(void) {
    return 0;
}

int main(void) {
    int val;
    val = func();
    printf("val = %d\n", val);
    return 0;
}

after

C89
#include <stdio.h>

static int func(void) {
    return 0;
}

int main(void) {
    const int val = func(); /* 宣言時に初期化! */
    printf("val = %d\n", val);
    return 0;
}

before_例2

C89
#include <stdio.h>

static int func(void) {
    return 0;
}

static int func2(int i) {
    return i + 1;
}

int main(void) {
    int val;
    int val2;

    val = func();
    val2 = func2(val);

    printf("val = %d\n", val);
    printf("val2 = %d\n", val2);
    return 0;
}

after_例2

C89
#include <stdio.h>

static int func(void) {
    return 0;
}

static int func2(int i) {
    return i + 1;
}

int main(void) {
    const int val = func(); /* 宣言時に初期化! */
    const int val2 = func2(val); /* 宣言時に初期化した変数を使って宣言時に初期化! */

    printf("val = %d\n", val);
    printf("val2 = %d\n", val2);
    return 0;
}

構造体の宣言時初期化とコンパイル時定数

構造体の初期化周りはコンパイル時定数でなくてはならないという制限がC89にはある。
つまり、下記のようなリファクタリングはC89だと無理(C99やC++03であれば可能)。

before

C89
#include <stdio.h>

typedef struct ST {
    int x;
}ST;

static int func(void) {
    return 0;
}

int main(void) {
    const int val = func();
    ST st;
    st.x = val;
    printf("val = %d\n", val);
    printf("st.x = %d\n", st.x);
    return 0;
}

after(error!)

C89
#include <stdio.h>

typedef struct ST {
    int x;
}ST;

static int func(void) {
    return 0;
}

int main(void) {
    const int val = func();
    const ST st = {val}; /* error: initializer for aggregate is not a compile-time constant */
    printf("val = %d\n", val);
    printf("st.x = %d\n", st.x);
    return 0;
}

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4