Nein, aber das liegt nur daran, dass der Speicher zugewiesen und mit einem Zeichentyp beschrieben wurde.
Speicher wird mit malloc zugewiesen. Dieses Objekt hat Typ nicht deklariert, da es mit malloc zugewiesen wurde. Somit hat das Objekt keinen effektiven Typ.
Anschließend greift der Code auf das Objekt zu und ändert es mit dem Typ char
. Da der Typ char
und kein Objekt eine effektive Art, die kopiert , Kopieren nicht die effektivste Art zu char
für diese und nachfolgende Zugriffe festgelegt, sondern setzt die effektive Art zu char
, nur für die Dauer der der Zugang . Nach dem Zugriff hat das Objekt keinen gültigen Typ mehr.
Dann wird der Typ int
verwendet, um auf dieses Objekt zuzugreifen und dieses nur zu lesen. Da das Objekt keinen effektiven Typ hat, wird es für die Dauer des Lesens int
. Nach dem Zugriff hat das Objekt keinen gültigen Typ mehr. Da int
offensichtlich mit dem effektiven Typ int
kompatibel war, ist das Verhalten definiert.
(vorausgesetzt, die Werte gelesen werden, nicht abfangen Darstellung für int
.)
Haben Sie zugegriffen und modifizierten, um die Aufgabe, einen nicht-Zeichentyp verwendet, die ebenfalls mit int
nicht kompatibel ist, wäre das Verhalten nicht definiert sein, .
Angenommen, Ihr Beispiel wurde (sizeof(float)==sizeof(int)
vorausgesetzt):
int i;
void *buf = calloc(5, sizeof(float)); // buf initialized to 0
{
float *ptr1 = buf;
for(i = 0; i < 5*sizeof(float); ++i)
ptr1[i] = (float)i;
}
int *ptr2 = buf;
for(i = 0; i < 5; ++i)
printf("%d", ptr2[i]);
Die effektive Art des Objekts, wenn float
s in geschrieben werden, wird vom Typ float
, für die Dauer des Schreib- und alle nachfolgenden Zugriffe auf das Objekt, die es nicht ändern . Wenn diese Objekte dann zugegriffen werden, indem der effektive int
Typ float
bleibt, da die Werte nicht nur modifiziert gelesen werden. Der vorherige Schreibvorgang mit float
setzt den effektiven Typ dauerhaft auf float
bis zum nächsten Schreibvorgang in dieses Objekt (was in diesem Fall nicht der Fall war). Die Typen int
und float
sind nicht kompatibel , daher ist das Verhalten nicht definiert.
(: ISO: Alle nachstehenden Text wird aus zitiert IEC 9899: 201x)
(6,5 Expressions 6)
Die effektive Typ eines Objekts für einen Zugriff auf seine gespeicherte Wert der deklarierte Typ des Objekts, falls vorhanden. 87) Zugewiesene Objekte haben keinen deklarierten Typ.
(6,5 Expressions 6)
Wenn ein Wert in ein Objekt gespeichert wird, einen Typ mit nicht deklarierten Typ durch einen L-Wert aufweist, der keine Zeichentyp ist, dann wird der Typ der L-Wert der effektiven Typ des Objekts für diesen Zugriff und für nachfolgende Zugriffe, die den gespeicherten Wert nicht ändern.
(6,5 Expressions 6)
für alle anderen zu einem Objekt zugreift keine deklarierten Typ aufweist, ist der effektive Art des Objekts einfach der Typ der L-Wert für den Zugriff verwendet.
(6,5 Expressions 8)
Ein Objekt hat seinen gespeicherten Wert nur durch einen L-Wert Ausdruck zugegriffen hat, die die folgenden Arten ein von hat: 88) - ein Typen kompatibel mit dem wirksamen Typ des Objekts, , - eine qualifizierte Version eines Typs, der mit dem effektiven Objekttyp kompatibel ist, - ein Typ, der dem Typ des Typs mit Vorzeichen oder Vorzeichen entspricht, - ein Typ mit oder ohne Vorzeichen entsprechend einer qualifizierten Version des effektiven Typs des Objekts, ein Aggregat oder Union Typ, der (ein Mitglied einer Unteraggregat oder enthaltenen Union einschließlich, rekursiv) oder einen des oben genannten Typs unter seinen Mitgliedern umfasst - einen Zeichentyp.
(6.5 Expressions 6)
Wenn ein Wert in ein Objekt kopiert wird unter Verwendung von Memcpy oder memmove nicht deklarierten Typ aufweist, oder wird als ein Array von Zeichentyps kopiert, dann wird der effektive Art des modifizierten Objekts für diesen Zugriff und nachfolgende Zugriffe die tun Ändern Sie den Wert nicht ist der effektive Typ des Objekts, von dem der Wert kopiert wird, wenn es einen Wert hat.
Sie einen interessanten Punkt implizit erhöhen, dass ich nicht gedacht hatte: da die zugewiesenen Speicher über eine 'int' lvalue nicht zugeordnet ist, hat es noch nicht„werden“ein' int' pro 6.5 Absatz 6, wenn es dereferenziert über ein 'int *', also doch striktes Aliasing? Das Parsen dieses Absatzes ist schmerzhaft. –
An diesem Punkt wurde nur ein Zeichen in das Objekt geschrieben und der effektive Typ wurde nicht auf das Objekt gesetzt. Bei allen anderen Zugriffen auf ein Objekt, das keinen deklarierten Typ hat, wird der tatsächliche Typ des Objekts einfach der Typ des für den Zugriff verwendeten lvalue. * – 2501
Wenn an demselben Punkt 'int 'wurde in das Objekt geschrieben, statt zu lesen, der Typ würde auch 'int' werden, weil: * Wenn ein Wert in einem Objekt gespeichert wird, das keinen deklarierten Typ durch einen lvalue mit einem Typ hat, der kein Zeichentyp ist, dann type des lvalue wird der effektive Typ des Objekts für diesen Zugriff und für nachfolgende Zugriffe, die den gespeicherten Wert nicht verändern. * – 2501