異機種間互換性の高いプログラムを書くために

KONOEは色々な計算機環境で開発・実行ができることを目指しています。 そのため、特定の開発環境に依存しない、できるだけ互換性の高いコードを 書くことを心掛ける必要があります。ここでは、これまでの経験から 特に注意すべき点をまとめます。

互換性が問題になるのは次のようなケースです。

1.言語仕様に依存する部分

C++の場合、文法上は例えばThe Annotated C++ Reference Manual(ARM)などで明確に 定義されています。文法を拡張したケースは、もはやC++のソースとは呼べない ものであり、ここでは考えません。

1.1.文法の解釈の拡張

見かけ上文法を満たしているが、拡張となっているもの。例えば配列の宣言 ではARMには
	declarator:
		...
		declarator [ constant-expressionopt ]
とあります。ところが、g++では「定数表現」であるべきところに 任意の表現を持ってくることができます。
	int	j = 100;
	int	a[ j ];
これは例えばSPARCompiler(CC)ではエラーになりますがg++ではOKです。正しくは
	const int	j = 100;
	int	a[ j ];
です。また、関数の仮引数の場合は
	void	func( int j ) {
		int	a[ j ];
	}
この場合はg++ではOKですが、CCではだめです。また、
	void	func( const int j ) {
		int	a[ j ];
	}
はCCでは許されません。

では、互換性を保つコーディングはどうあるべきでしょうか。同じARMで

	new-declarator:
		...
		new-declaratoropt [ expression ]
となっています。newの中なら任意の表現が許されることになります。上の例は
	void	func( const int j ) {
		int	* a = new int[ j ];
	}
とする必要があります。実際のaの使い方は配列要素取り出し演算子[]を 使って同じように扱えます。deleteが必要になるところが違いますが。

1.2.古い規格と新しい規格

現在C++はB.Stroustrupの実質標準的な言語仕様のもの(ATT版)と、ANSIで 規格化がすすめられているものの間で差異があります。例えば
	for( int i = 0; i < 100; i ++ ) { /*...*/ }
	for( int i = 0; i < 100; i ++ ) { /*...*/ }
これは例えばC++ではiが二度宣言されているというエラーになりますが、 g++では正しいと扱われます。iはANSIでは{}の中で定義されているように 扱いますが、古いCCでは{}の外、forの置かれたレベルで定義されたと 考えます。そのためにこのような結果になります。逆に
	for( int i = 0; i < 100; i ++ ) { /*...*/ }
	for( i = 0; i < 100; i ++ ) { /*...*/ }
この場合、CCでは問題なく通りますが、g++ではスコープルールからiは 最初のforの{}の中に定義されているので次のforでは見えない。旧式の 規格だと文句をいってくれます。

2.実装に依存する部分

3.システムに依存する部分



[collaboration/compatibility.html] Last Modified : 13-Sep-1997.

KONOEコラボレーション konoe-req@konoe.kek.jp