Wenn nun ANZAHLELEMENTE von 2 auf 3 erhöht wird, ohne, dass bei
INITIALISIERUNG ein dritter Wert eingetragen wird, wird das dritte
Element im Array automatisch auf 0 gesetzt.
Heute hatten wir so einen Fall, was dann zu einem Crash geführt hat,
weil auf eine illegale Adresse (0) zugegriffen wurde.
Frage:
Kann man diese implizite Null-Initialisierung ausschalten oder
wenigstens eine Warnung ausgeben lassen?
Besser: Mit NULL initialisieren und im Code initialisieren und als
Fehlerfall prüfen. Dann fliegt auch einem unbedarften späteren
Entwickler der Kram nicht um die Ohren.
Frank Roggel schrieb:> Frage:> Kann man diese implizite Null-Initialisierung ausschalten oder> wenigstens eine Warnung ausgeben lassen?
Was soll erwartest du als Ergebnis, wenn der dritte Wert nicht
initialisiert wird?
Frank Roggel schrieb:> Heute hatten wir so einen Fall, was dann zu einem Crash geführt hat,> weil auf eine illegale Adresse (0) zugegriffen wurde.
NULL beseutet ungültige Adresse.
Das Element im Array wurde nicht initialisiert, also ist es ungültig.
Um den Fehler abzufangen muss darauf im Code reagiert werden!
Ob das Programm abstürzt, weil du auf NULL zugreifst oder eine andere
ungültige Adresse ist egal.
Bei NULL hast du die Chance es zu erkennen.
Da die Funktion zugriff() einen void-Rückgabetyp besitzt, jedoch in der
Funktion eine Rückgabe eines int32_t * erfolgt, wird das ganze auch
nicht kompilieren. Dann ist es auch völlig egal, ob irgendwelche
Arraygrenzen überschritten oder falsch initialisierte Werte
zurückgegeben würden.
Irgendwer schrieb:> Beim aufruf von zugriff muss dann natürlich geprüft werden ob der> Rückgabewert überhaupt gültig ist bevor er verwendet werden darf:
Wenn bei ungültigen Feldern eine 0 drin steht, kann er auch direkt auf
das Array zugreifen.
Da bringt deine Funktion gar nichts.
x^y schrieb:> uint32_t* adressen[] = { INITIALISIERUNG };>> uint32_t zugriff(int element)> {> uint32_t result = 0;> if ((element >= 0) && (element < COUNT(adressen)))> result = adressen[element];> return result;> }>> Sofern negative Indizes hier ohnehin nicht definiertes Verhalten sind,> bietet sich uint32_t für element an.
Das haut nicht hin.
In dem Array werden Adressen gespeichert.
Darum muss result auch vom Typ dieser Adressen sein. Und der
Rückgabewert der Funktion auch.
Frank Roggel schrieb:> Wenn nun ANZAHLELEMENTE von 2 auf 3 erhöht wird, ohne, dass bei> INITIALISIERUNG ein dritter Wert eingetragen wird, wird das dritte> Element im Array automatisch auf 0 gesetzt.> Heute hatten wir so einen Fall, was dann zu einem Crash geführt hat,> weil auf eine illegale Adresse (0) zugegriffen wurde.>> Frage:> Kann man diese implizite Null-Initialisierung ausschalten
Dann würde das dritte Element eben einen zufälligen Wert haben.
Inwiefern ist das besser als eine definierte 0?
> oder wenigstens eine Warnung ausgeben lassen?
Ich könnte schwören, so eine Warnung mal gesehen zu haben, aber finde
sie nicht mehr. ich glaube, es gibt sie nur für Elemente von Strukturen,
nicht von Arrays.
Frank Roggel schrieb:> Wenn nun ANZAHLELEMENTE von 2 auf 3 erhöht wird, ohne, dass bei> INITIALISIERUNG ein dritter Wert eingetragen wird, wird das dritte> Element im Array automatisch auf 0 gesetzt.> Heute hatten wir so einen Fall, was dann zu einem Crash geführt hat,> weil auf eine illegale Adresse (0) zugegriffen wurde.
Falsch. Das Programm stuerzt nicht ab, weil auf eine (illegale) Adresse
zugegriffen wird. Es muss nicht mal abstuerzen, denn ihr habt da
undefined behavior gebaut.
Der Pointer wird zwar (impliziet) mit 0 initialisiert, aber die
dereferenzierung eines NULL Pointers ist UB.
Gegenfrage: Mit was soll die Adresse denn sonst initialisiert werden,
wenn nichts angegeben wird? Dann ist es ein nicht initialisierter
Pointer. Damit haette das Programm auch abstuerzen koennen, oder auch
nicht. Denn auch das ist UB.
Frank Roggel schrieb:> Frage:> Kann man diese implizite Null-Initialisierung ausschalten oder> wenigstens eine Warnung ausgeben lassen?
Ihr koennt einfach euren Code reparieren, wie waer's damit?
Kaj schrieb:>> Heute hatten wir so einen Fall, was dann zu einem Crash geführt hat,>> weil auf eine illegale Adresse (0) zugegriffen wurde.> Falsch. Das Programm stuerzt nicht ab, weil auf eine (illegale) Adresse> zugegriffen wird.
Wie kommst du darauf? Woher weißt du, warum das Programm abgestürzt ist?
> Es muss nicht mal abstuerzen, denn ihr habt da undefined behavior gebaut.> Der Pointer wird zwar (impliziet) mit 0 initialisiert, aber die> dereferenzierung eines NULL Pointers ist UB.
… und hat in diesem Fall offenbar zum Absturz geführt.
Johann L. schrieb:> #define ARRAY_SIZE(X) (sizeof(X) / sizeof(*(X)))> _Static_assert (ANZAHLELEMENTE == ARRAY_SIZE (adressen), "Bug");
Perfekt, das tut's! Danke!
Irgendwer schrieb:> deine Funktion hat sowieso zwei fehler. Das "void & return" und das
Ja stimmt, sorry. Hab das nur als Beispiel runtergetippt, da tatsächlich
Situation, ist etwas komplexer.
Kaj schrieb:> Falsch. Das Programm stuerzt nicht ab, weil auf eine (illegale) Adresse> zugegriffen wird.
Konkret gab es einen Trap/Exception.