読者です 読者をやめる 読者になる 読者になる

Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

C言語の不可解なエラー(GCC) - 配列の宣言時にconst変数を指定したとき

スポンサードリンク

f:id:fa11enprince:20150730081021j:plain
stackoverflowで英語の練習を兼ねてダメダメ英語を連投してました。
そのうち迫害されるんじゃないかと思います(*´Д`)
そんなわけで、Cのプログラムを書いていたのですが……
不可解なエラーが……

問題になったコード

#include <stdio.h>
#include <string.h>

const int MAXLINE = 1000;

// Dummy Array
static char fooString[2][MAXLINE] = {
   "abcdefg\n",
   "hijklm\n"
};

// Dummy function
int myGetline(char **line, int maxline) {
    static int i = 0;
    char *tmp = fooString[i++];
    if (strlen(tmp) > maxline) {
        *line = '\0';
        return 0;
    }
    *line = tmp;
    return strlen(tmp);
}

int main(int argc, char *argv[]) {
    char *line = NULL;
    long lineno = 0;
    // ...
    return 0;
}

コンパイル

$ gcc -o foo.exe foo.c
foo.c:9:13: エラー: ファイルスコープの可変 ‘fooString’ です
 static char fooString[2][MAXLINE] = {
             ^
foo.c:10:4: 警告: char の配列にとって初期化子文字列が長すぎます
    "abcdefg\n",
    ^
foo.c:10:4: 警告: (‘fooString[0]’ 用の初期化付近)
foo.c:12:1: 警告: char の配列にとって初期化子文字列が長すぎます
 };
 ^
foo.c:12:1: 警告: (‘fooString[1]’ 用の初期化付近)

ハッ?全く意味が分からないエラーだ……
そういえばCの古いコンパイラって配列の宣言に
const使えないんだっけってことを30分後に気付く。

対策法1

gccで不当ならg++でC++としてコンパイルでエイッ!

$ g++ -o foo.exe foo.c

コンパイル成功。

対策法2(だめでしたー)

いやいやC++じゃなくてCで何とかしろよって場合は

$ gcc -std=c99 -o foo.exe foo.c
foo.c:9:13: エラー: ファイルスコープの可変 ‘fooString’ です
 static char fooString[2][MAXLINE] = {
             ^
foo.c:10:4: 警告: char の配列にとって初期化子文字列が長すぎます
    "abcdefg\n",
    ^
foo.c:10:4: 警告: (‘fooString[0]’ 用の初期化付近)
foo.c:12:1: 警告: char の配列にとって初期化子文字列が長すぎます
 };
 ^
foo.c:12:1: 警告: (‘fooString[1]’ 用の初期化付近)

あれ?C99はOKなんじゃなかったっけ?

対処法3

まぁこれが妥当ですね。諦めて#defineを使う

#include <stdio.h>
#include <string.h>

// const int MAXLINE = 1000;
#define MAXLINE 1000

// Dummy Array
static char fooString[2][MAXLINE] = {
   "abcdefg\n",
   "hijklm\n"
};

// Dummy function
int myGetline(char **line, int maxline) {
    static int i = 0;
    char *tmp = fooString[i++];
    if (strlen(tmp) > maxline) {
        *line = '\0';
        return 0;
    }
    *line = tmp;
    return strlen(tmp);
}

これでコンパイルが通ります。
C言語はこれだから嫌だ……。
妙に古臭いところが残ってるんですよね…。いい言語には違いないのですが。
好きなC++はそれはそれでSTLで長編小説なエラーが出るという……。