8

Es ist mein Verständnis, dass so etwas wie dies in Ordnung ist:Ist es okay für int ** und const int ** zu alias?

const int ci = 42; 
const int *cip = &ci; 
int *ip = (int *)cip; 
int j = *ip; 

Was ist das?

const int ci = 42; 
const int *cip = &ci; 
const int **cipp = &cip; 
int **ipp = (int **)cipp; 
int j = **ipp; 
+0

'int * ip = (int *) cip;' ist nicht OK. Ihr Compiler sollte sich darüber beschweren, dass er die "const" ablegt. Wenn nicht, verwenden Sie höhere Warnstufen. Oder an was für ein "OK" denkst du? "funktioniert", "arbeitet zuverlässig", "funktioniert portabel", "ist guter Code", ... – Yunnosch

+7

@Yunnosch: Nein. Es ist vollkommen in Ordnung. Die explizite Besetzung ist eigentlich, wie Sie * dem * Compiler, den Sie * wirklich wollen * das * const' verraten. Auf diese Weise sagen Sie dem Compiler, keine Warnungen auszugeben.Das erste Code-Snippet ist absolut legal C. – AnT

+0

@AnT Für den gezeigten Code wird das Verbergen der Konstanten nicht benötigt. Für anderen Code, der eine const verschüttet, die einen Zweck hat, ist keine gute Idee. Ich gebe jedoch zu, dass ich Compilerwarnungen mit der Art von piepsigen Warnungen verwechselt habe, die von extrem strikten statischen Codeanalysatoren erzeugt wurden; welches ich für Code im Job verwenden soll. Sie brauchen mehr als eine Besetzung, um mit dem Nörgeln aufzuhören. Es ist irgendwie in mein Denken eingebrannt. – Yunnosch

Antwort

5

Der Ausdruck *ipp ist ein L-Wert vom Typ int * jedoch ist es const int * ein Objekt des effektiven Typs zuzugreifen verwendet wird. (Nämlich, cip).

Nach dem Buchstaben des Standards ist es eine strenge Aliasing-Verletzung: die Liste der zulässigen Typen zu Alias ​​enthält keine Aliasing T * als const T * oder umgekehrt.

Die nächstgelegene Ausnahme ist diese: (C11 6,5/6 Auszug)

  • eine qualifizierte Version eines Typs kompatibel mit dem wirksamen Typ des Objekts

„qualifizierte Version "ist eindeutig definiert durch C11 6.2.5/26:

Jeder unqualifizierter Typ hat mehrere qualifizierte Versionen seines Typs, entsprechend den Kombinationen von einem, zwei oder allen drei der const, volatile und restrict Qualifier. Die qualifizierten oder nicht qualifizierten Versionen eines Typs sind unterschiedliche Typen, die zu derselben Typkategorie gehören und die gleichen Darstellungs- und Ausrichtungsanforderungen aufweisen. Ein abgeleiteter Typ wird nicht von den Qualifikationsmerkmalen (falls vorhanden) des Typs, von dem er abgeleitet wird, qualifiziert.

So ist die Ausnahme ist, dass T als const T und umgekehrt aliased werden, aber es gibt keine ähnliche Ausnahme für Zeiger auf aliasable Typen. const T * ist keine qualifizierte Version von T *.


Allerdings gibt es natürlich die Fußnote:

Die Absicht dieser Liste jene Umstände angeben, in dem ein Objekt kann oder nicht

aliased werden

I couldn‘ t sagen, ob die Absicht der Regel für const T * und T * aliasable oder nicht ist. Es scheint mir unklar zu sein, was der Zweck der Festlegung, dass T * und const T * "die gleichen Darstellung und Ausrichtung Anforderungen" (6.2.5/28) haben, wäre, wenn es nicht aliasable ist.

+1

Die Tatsache, dass eine Garantie nur dann nützlich wäre, wenn sie als Ausnahme von Aliasing-Regeln behandelt würde, bedeutet nicht mehr, dass Compiler-Schreiber sie als eine interpretieren. Die Common Initial Sequence-Garantien sind grundsätzlich nutzlos unter gcc und clang, außer im "no strict aliasing" -Modus. Nachdem dies gesagt wurde, nimmt noch keiner der Compiler * an, dass auf ein "int * p" nicht mit einem "int const ** p" zugegriffen wird oder umgekehrt; Ich weiß nicht, ob das so bleiben wird. – supercat

Verwandte Themen