bcc32でポインタを操作した際の挙動について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

トピックに返信する


答えを正確にご入力ください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: bcc32でポインタを操作した際の挙動について

Re: bcc32でポインタを操作した際の挙動について

#4

by タカ » 5年前

回答ありがとうございます。納得しました。(お恥ずかしい。安易にコンパイラを疑うべきではなかったです)

データの破壊を意図的に起こす実験ではあったのですが、最適化を考慮できていなかったです。
定義した変数にvolatileを付けたところ、データの破壊を確認できました。

Re: bcc32でポインタを操作した際の挙動について

#3

by みけCAT » 5年前

ポインタの操作において、
普通の(配列でない)変数は1要素の配列として扱います。 (N1570 6.5.6 Additive operatorsの7)
c++;により、cはbの「1つ次」の要素を指すようになります。
これは範囲外であり、「1つ次」の要素を指すポインタを生むことはOKですが、
それを単項*演算子でデリファレンスしてはいけないと定められています。 (N1570 6.5.6の8)
タカさんのプログラムはこれに違反しており、未定義動作となります。 (N1570 4. Conformanceの2)
未定義動作なので、何が起こってもおかしくなく、bcc32ではなくタカさんのプログラムのバグです。

printf( "a:%d\n",&a );をコメントアウトした場合、
aは最初に1を代入する以外に値を書き換えることもポインタを使うこともなく、
定数として扱うことができると考えられるので、
実際に最適化によりaが定数に置き換わり、範囲外への書き込みによるデータの破壊を免れた可能性が考えられます。

ちなみに、printfで%dに対応するデータとしてポインタを渡すのも、
型の不一致で未定義動作になります。 (N1570 7.21.6.1 The fprintf functionの9)
ポインタを出力するには、void*にキャストして書式%pを使うのがいいでしょう。

Re: bcc32でポインタを操作した際の挙動について

#2

by box » 5年前

a と *cは同じアドレスを差しており、
論拠は何ですか?

bcc32でポインタを操作した際の挙動について

#1

by タカ » 5年前

初めての質問になります。

bcc32 コンパイラにてC言語の勉強をしていたところ、不可解な現象に遭遇しました。
現象的に、bcc32のバグではないかと考えているのですが、如何でしょうか。

bcc32のバージョン:
Borland C++ Compiler 5.5

質問したいこと:
1.自分のPC以外でも、同様の現象が発生するか
2.何故このような現象が発生するのか(可能であれば)

コード:

#include <stdio.h>

int main()
{
	char a, b;
	char *c;
	
	a=1;
	b=2;
	c = &b;
	c++;
	*c = 3;

	printf( "a:%d\n",&a );/* コメントアウトすると結果が変わる */
	printf( "b:%d\n",&b );
	printf( "c:%d\n",c );

	printf( "a:%d\n",a );
	printf( "b:%d\n",b );
	printf( "c:%d\n",*c );

	return 0;
}
実行結果(コメントアウトしない場合):
a:1638228
b:1638227
c:1638228
a:3
b:2
c:3

実行結果(コメントアウトした場合):
b:1638227
c:1638228
a:1
b:2
c:3

仮説:
a と *cは同じアドレスを差しており、 *c の変更は a にも反映されるはず。
しかし、 &a を参照する処理がない場合、 *c の変更は a に反映されない。
そのような仕様はC言語には存在しないため、バグではないか。

ページトップ