こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

registerと配列

ある本に以下のような書き出しでプログラムが載っています。
>register付きで宣言された配列の先頭要素の値を表示(動作しない)<
#include<stdio.h>

int main(void)
{
register int x[5];

printf("x[0]の値は%dです。\n",x[0]);

return 0;
}
配列はコンパイルする段階で*(a+0)とポインタに変換されるとは理解しているのですが、私の環境(Red Hat Linux)では動作してしまいます。
さすがに、
printf("&x[0]の値は%pです。\n",&x[0]);とすると>registerにかかわらずポインタの値を求めています<という警告がでますが、
本では>動作しない<と書かれていますが、きちんとコンパイルも行われ>動作します<
これはどの様に考えたらよいのでしょうか?宜しく願います。

投稿日時 - 2008-07-07 05:17:01

QNo.4157242

困ってます

質問者が選んだベストアンサー

基本的には#2の通りです。
ただし、JIS X3010:2003の5.1.1.3 診断メッセージには、

前処理翻訳単位又は翻訳単位が何らかの構文規則違反又は制約違反を含む場合(たとえ, その動作が未定義の動作又は処理系定義の動作として明示的に規定されていても), 規格合致処理系は, その前処理翻訳単位又は翻訳単位に対して, 少なくとも一つの(処理系定義の方法で識別される)診断メッセージを出力しなければならない。

とありますので、警告すら出ないのは処理系の問題です。
GCCの場合、-pedanticオプションを付けないと規格合致処理系にはならないように思います。

投稿日時 - 2008-07-07 17:37:13

お礼

いつも的確なご回答有難うございます。
今後もよろしく願います。

投稿日時 - 2008-07-08 05:30:15

ANo.3

このQ&Aは役に立ちましたか?

19人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

「動作しない」は言い過ぎです.
まず「register という記憶クラス」はコンパイラに対するヒントですから, 「記憶クラス register が指定されていてもメモリ上に配置する」ことはかまいません. ただし, たとえメモリ上に配置したとしても register が付いているかのように振舞う必要があります. 例えば, (メモリ上だからアドレスが存在するとしても) 単項& でアドレスをとるようなことは許されていません.
ということで「記憶クラスとして register を持つ配列に対し sizeof 以外の演算を行う」ことは未定義動作です (ISO C, 6.3.2.1, 6.7.1). ですから, 「結果的に期待した通りの動作をする」可能性はあります.

投稿日時 - 2008-07-07 13:19:18

ANo.1

その本は特定の環境における動作について書かれているように思います
コンパイラによっては配列のregisterを無視してスタック上にメモリを確保するものもあるでしょう

投稿日時 - 2008-07-07 09:45:54

あなたにオススメの質問