Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

きっかけ

業務として初めて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;
}

yoyomion
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした