-
Notifications
You must be signed in to change notification settings - Fork 3
use of variables
XcodeML/C(0.9)において、arrayRefは次のように定義されている。
配列への参照には、以下の要素を用いる。
- arrayRef - 配列の先頭要素のアドレスを参照する式。内容に配列名を指定する。
- arrayAddr - 配列のアドレスを参照する式。内容に配列名を指定する。
配列要素への参照は、arrayRefを用いてアドレス計算し、pointerRefで要素にアクセスする。変数参照の要素と同様に、scope属性を使い局所変数を区別する。
特に、arrayRefは子要素を持たない。
一方XcodeML/C++(1.2)において、arrayRefは次のように定義されている。
7.4 arrayRef要素 配列要素a[i]への参照を表現する。
<arrayRef> arrayAddr要素 式の要素 </arrayRef> 属性(必須): type
例: int a[3]; と宣言されているとき、配列要素 a[i] の参照は、
<arrayRef type="int"> <arrayAddr type="A5”scope="local">a</arrayAddr> <Var type="int" scope="local">i</Var> </arrayRef>
のように表現される。配列要素のアドレス &a[i] の参照は、
<addrOfExpr type="P232"> <arrayRef type="int"> <arrayAddr type="A5”scope="local">a</arrayAddr> <Var type="int" scope="local">i</Var> </arrayRef> </addrOfExpr>
のように表現される。ここでP232はint型へのポインタと宣言されている。後者はarrayAddr要素でないことに注意されたい。
このふたつは異なるが、意図されたものか。
上の問題に関連して、C_Frontは子要素をもつarrayRef要素を出力する。
たとえば、次のようなCプログラムに対して、
void f() {
int a[3] = {1, 2, 3};
a[0] = a[1];
}
C_Frontは次のXcodeMLを出力する。
<exprStatement lineno="3" file="array.c">
<assignExpr type="int">
<arrayRef type="int">
<arrayAddr type="A0" scope="local">a</arrayAddr>
<intConstant type="int">0</intConstant>
</arrayRef>
<arrayRef type="int">
<arrayAddr type="A0" scope="local">a</arrayAddr>
<intConstant type="int">1</intConstant>
</arrayRef>
</assignExpr>
</exprStatement>
これは
配列要素への参照は、arrayRefを用いてアドレス計算し、pointerRefで要素にアクセスする。変数参照の要素と同様に、scope属性を使い局所変数を区別する。
に反する。
次のCプログラム
void f() {
int a3i[] = {1, 2, 3};
int *pi = &(a3i[1]);
}
は、C_Frontによって以下のXcodeMLに変換される。
<varDecl lineno="3" file="array-dacay.c">
<name>pi</name>
<value>
<addrOfExpr type="P0">
<arrayRef type="int">
<arrayAddr type="A0" scope="local">a3i</arrayAddr>
<intConstant type="int">1</intConstant>
</arrayRef>
</addrOfExpr>
</value>
</varDecl>
ここで、addrOfExprはXcodeML/C Version 0.9Jで定義されていない。C_FrontかXcodeML/Cのどちらかを修正するべきである。
addrOfExprはXcodeML/C++ V1.0J以降でも(未定義で)使われている。
関係しそうなので引用。
以下の表のうち、「C言語表現」で &
がついているものは全て addrOfExpr を使って表現した方が直交性が高くなり、
また「配列のアドレス」と「配列の要素のアドレス」を区別できない問題も解決できるので、
addrOfExpr を仕様に追加することを強く提案する。
要検討:構造体まわりの現在のC_Frontの変換仕様について
arrayRef
要素([-@sec:expr.array]節)とmemberArrayRef
要素、arrayAddr
要素([-@sec:expr.var]節)とmemberArrayAddr
要素は、それぞれ名前が似ているが意味の対称性がない。少なくとも名前を再考したい。他の点でも、今後構造体やクラスへの対応を考えると、整理しておきたいところ。
C言語表現 XcodeML表現 C言語表現 XcodeML表現 v
* Var v
s.v
* memberRef v
** varAddr s
&v
* varAddr v
&s.v
* memberAddr v
** varAddr s
a
* arrayAddr a
s.a
* memberArrayRef a
** varAddr s
&a
* arrayAddr a
&s.a
* memberArrayAddr a
** varAddr s
a[i]
* arrayRef
s.a[i]
* pointerRef
** arrayAddr a
** plusExpr
** Var i
*** memberArrayRef a
**** varAddr s
*** Var i
&a[i]
* addrOfExpr
&s.a[i]
* plusExpr
** arrayRef
** memberArrayRef a
*** arrayAddr a
*** varAddr s
*** Var i
** Var i
(メンバの参照の要素(C++拡張) {#sec:expr.member})