厳密なエイリアシング規則により、ポインターが異なるタイプをポイントする場合は、任意のデータ型にエイリアシング可能な char*
および void*
を除き、ポインターはエイリアシングしないと想定されます。これを次の図に示します。この図では、オブジェクト ユニバースと関連のポインターを示します。
図 1. オブジェクト ユニバース
- ポインターはタイプ ユニバース U(T) で関連付けられている
- T はテンプレートです。上の図には、
int
ユニバース、float
ユニバースなどのテンプレートが示されています。また、デザインごとにMyClass
ユニバースもあります。さらに、デフォルトですべてのユニバースを含むchar
ユニバースがあります。 - ユニバースはエイリアシングしない
- ポインター
p
は、int
ユニバース内のアドレスのみをポイント可能で、ポインターq
はfloat
ユニバース内のアドレスのみをポイント可能です。そのため、ポインターp
とポインターq
はエイリアシングできません。 - 派生ポインターは元のユニバースをポイント
- restrict ポインターから派生したポインターは restrict ポインターとなり、同じ制限されたメモリ領域をポイントします。詳細は、派生ポインター を参照してください。
-
char*
ユニバースはすべてのユニバースを含む -
char
ポインターは、すべてのユニバースのどの変数でもポイントできます。
次の図に示す 2 つのポインター p
および q
は同じタイプ (int
) で、コンパイラによりエイリアシングが適用され、パフォーマンスが低下します。
図 2. パフォーマンスの低下
次の図に示す例では、ポインター p
は int
、ポインター q
は float
であり、コンパイラにより厳密なエイリアシング規則が適用され、エイリアシングが存在する場合は動作が予期しないものになります。
図 3. タイプの異なる 2 つのポインター