-
18-09-2019 - |
質問
は、以下の変換に安全ですか?
int b[10][10];
char *x;
int a[]={0,1,2,3,4,5,6,7,8,9};
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
b[i][j]=a[i];
for(x=(char *)&b[0];x<=(char *)&b[9][9];x+=sizeof(a+1)) // Problem lies here!
printf("%d\n",*x);
とは思わない上記の変換は、 for
ループは安全であると思うのでは、プラットフォームにより異なります)。題がある可能性がありますをつくって、そこから生まれる.私が驚いたので、コードの統を与えることなく警告も行の -Wall -pedantic
オプションgcc.
解決
ここはチャンスの法的のために一つだけの理由:2次元 int
配列オブジェクトでは捉としての配列 char
オブジェクト。が一般の場合にはメモリの再解釈が定義されていない動作の言語仕様の明示的にできる"配列[符号付き/符号なし]char"reinterpretationsオブジェクトのタイプです。
しかし、形式的安全性の問題は続いております。の言語とを保証するものではありません任意ビットパターンが有効な値 char
タイプです。お読み込捉のメモリを通じて char
では理論的に原因が未定義の場合の動作ではトラップとの出会いの表現のために char
.るために、安全でここにしてい unsigned char
タイプすることが確認されるタイプなトラップの表現となります。もちろん、プラットフォームトラップ char
きたいというエキゾチック".
この間、お sizeof(a + 1)
見えないからくるものなのかということである。 a + 1
表現の int *
タイプです。ぜん使いたいのポインタサイズの増加お x
値がこの場合は明らかでない。どのようなごうとして目指すものは何か
て、警告...かのコンパイラ関係の警告です。GCCが警告しいタイプpunning(通称メモリを再解釈で char
reinterpretationsは明示的に認められてい上、警告です。また、明示的にかぶり、通常の傾向を抑制する他の警報が出ていることにつながるので語のコンパイラがいったい何かにかかわらず間違いおよび/または危険でなのかもしれません。
他のヒント
char *に任意のポインタ型のキャストが明示的にC言語で許可されています。これこれのほとんどは大丈夫です。
for(x=(char *)&b[0]; x <= (char *)&b[9][9]; x += sizeof(a+1))
最初の部分はx = (char*)&b[0];
は、配列の先頭に文字ポインタを確立結構です。テストでもある微細x <= (char *)&b[9][9]
は、アレイ内のX点限り真であろう。
x += sizeof(a+1)
はあやふやな部分です。ほとんどの32ビットCPUアーキテクチャのはsizeof(int型*)だけ<全角>に全角>はsizeof(int型)と同じであることを起こるので、このコードはおそらく仕事のが、唯一の事故でをします。
私は何を意図していたことx += sizeof(a[0])
またはx += sizeof(b[0])
だったと確信しているが、コードが実際に意図されたものでしたから、誰がバグに気づいていません。