int i='abcd' は規格範囲内?

[戻る]
shin 2002/07/31(水) 23:24:39
あるプログラムを読んでいる時、次のような構文に出くわしました。
int i = 'abcd';
これはANSI C(C89/C99)で認められているのでしょうか?

Visual C++6.0+SP5では確かに4文字(バイト)分のASCIIコードが
順番にiに入っていました。
が、Microsoft固有の方言なのか否かを知りたくて質問致しました。

どうぞ宜しくお願い致します。

YuO [E-Mail] 2002/08/01(木) 00:34:15
基本的には認められます。sizeof(int)文字を越えたらダメでしょうけどね……。
#でもって,sizeof(int)が実装依存。

以下は,ISO/IEC 9899:1999の6.4.4.4 Character constantsからの引用です。

まず,文字定数の文法。
> Syntax
> 1
> character-constant:
>     ' c-char-sequence '
>     L ' c-char-sequence '
> c-char-sequence:
>     c-char
>     c-char c-char-sequence
> c-char:
>     any member of the source character set except the single-quote ',
backslash \, or new-line character
>     escape-sequence
#escape-sequenceの定義は省略

でもって,
> Semantics
> 10 An integer character constant has type int.
>    The value of an integer character constant containing a single character
that maps to a single-byte execution character is the numerical value of the
representation of the mapped character interpreted as an integer.
>    The value of an integer character constant containing more than one
character (e.g., 'ab'), or containing a character or escape sequence that does
not map to a single-byte execution character, is implementation-defined.
#以下省略
というわけで,''内に複数文字を書いた場合,実装定義の動作になります。

wood 2002/08/01(木) 06:06:44
>int i = 'abcd';
本当にこの記述でしたか
int i = "abcd";
ではありませんでしたか
なお、intはハードウェアまたは、OSに左右されるとなっているはずです
このことから有効なはずですけど

YuO さんの言わんとしていることは、私には良くわかりません

なお、コンパイルオプションでマイクロソフトの拡張(固有表現)を無視する
ことができたはずですけど

PATIO 2002/08/01(木) 09:47:43
YuOさんが言われていることは、コンピュータ内では文字も所詮はバイナリコードである
という部分に繋がっています。バイナリコードであれば、あとはコンパイラの解釈つまり、
実装依存になるということです。abcdのバイナリコードを順に並べた結果、intの範囲を
超えなければ、代入可能という判断になるかと思います。
まあ、32ビット機の場合、普通に考えるとintは4バイトになりますから、
4桁の文字列まではバイナリとして扱えば、intに代入可能ということになりますね。
結局、コンパイラの実装依存になるので望ましいコードとはいえませんけれど。

yas0302 2002/08/01(木) 10:11:48

wood さんの

> int i = "abcd";

これは意味が違いますね。アドレスが入ってしまいます。
(その前にコンパイラに怒られるけど)

int i = 'abcd';

という表現は、文字定数ということで
認められているんじゃないですか。

YuO さんの文章と同じような内容ですが、

K&Rの プログラミング言語Cに記述されています。

文字定数は、'x'のように単一引用符で囲まれた一つ以上の文字の列である。
単一の文字からなる文字定数の値は実行時のマシンの文字セット中の文字の数値となる。
多くの文字からなる定数の値は処理系ごとに定義される。
・・・・・・・

とあります。
Microsoft固有でないことだけは確かですね。

YuO [E-Mail] 2002/08/01(木) 20:48:27
> YuO さんの言わんとしていることは、私には良くわかりません

とりあえず,C89/C99という表現があったので仕様書から引用しておきましたが……。
int i = 'abcd';
が可能かどうかは,Sematicsの文の3文目を読めば書いてあります。
実行コード系がASCII,intの幅が32bitとして,iの値が
・0x61626364
・0x64636261
・0x61
・0x64
・0x18A ( = 0x61 + 0x62 + 0x63 + 0x64 )
などは全て規格を満たします。
#もちろん,これを「許さない」もアリ。

> int i = "abcd";

一応,これも実装依存の値がiに入るか,未定義の振る舞いになるかです。
"abcd"というchar [5]型の定数は標準変換によってchar *型になり,
#ISO/IEC 9899:1999 6.3.2.1 Lvalues, arrays, and function designators
すべてのポインタ型は整数型に変換できるためです。
#ISO/IEC 9899:1999 6.3.2.3 Pointers
ただし,後者はC言語の規格においてのみ許される変換です。C++言語では許されません。
#ISO/IEC 14882:1998 4.10 Pointer Conversions

ちなみに,int i = 'abcd';はC++言語に置いてもC99と同じ扱いです。
#ISO/IEC 14882:1998 2.13.2 Character literals

shin 2002/08/01(木) 23:56:27
[[解決]]
みなさん、どうもありがとうございました。

文法は認められているが、実際の挙動は環境に依存するのですね。
従って、「この構文は使うべきではない」という結論が得られました。

今後とも宜しくお願いいたします。

古いスレッドには追加発言できません。