Hier ist mein Code:
#include <string.h>
#include <stdio.h>
typedef char BUF[8];
typedef struct
{
BUF b[23];
} S;
S s;
int main()
{
int n;
memcpy(&s, "1234567812345678", 17);
n = strlen((char *)&s.b) / sizeof(BUF);
printf("%d\n", n);
n = strlen((char *)&s) / sizeof(BUF);
printf("%d\n", n);
}
Wenn Sie gcc 8.3.0 oder 8.2.1 mit einer beliebigen Optimierungsstufe verwenden -O0
, wird dies ausgegeben , 0 2
wenn ich es erwartet habe 2 2
. Der Compiler hat entschieden, dass das strlen
an b[0]
den Wert, durch den geteilt wird, gebunden ist und ihn daher niemals erreichen oder überschreiten kann.
Ist das ein Fehler in meinem Code oder ein Fehler im Compiler?
Dies ist im Standard nicht klar formuliert, aber ich dachte, die gängige Interpretation der Zeigerherkunft war, dass X
der Code für jedes Objekt (char *)&X
einen Zeiger generieren sollte , der über die gesamte Iteration iterieren kann X
- dieses Konzept sollte auch dann gelten, wenn X
dies der Fall ist Sub-Arrays als interne Struktur.
(Bonusfrage, gibt es ein gcc-Flag, um diese spezielle Optimierung auszuschalten?)
2 2
unter verschiedenen Optionen.
s.b
beschränkt ist, gibt b[0]
es zwei Optionen: (1) Zugriff außerhalb der Grenzen, falls 8 Nicht-Null-Zeichen vorhanden sind, dh UB, (2) gibt es ein Null-Zeichen, in dem Die Länge ist kleiner als 8, daher ergibt das Teilen durch 8 Null.