Warum dieser Behandlungsunterschied?
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
(Alles in Ordnung) . . .
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
Warning: 'k' may be used uninitialized in this function [-Wmaybe-uninitialized]
|
Anzeige
|
C: Deklaration und InitialisierungWarum dieser Behandlungsunterschied?
(Alles in Ordnung) . . .
Warning: 'k' may be used uninitialized in this function [-Wmaybe-uninitialized] Im ersten Fall wird "k" automatisch mit 0 initialisiert, das ist für globale und statische Variablen vom C-Standard so vorgegeben. Lokale Variablen werden hingegen nicht automatisch initialisiert und enthalten irgendeinen Wert solange sie nicht explizit beschrieben werden.
Fas eone k liegt im statischen mot 0 initialisierten Speicher, das andere k auf dem Stack und enthält in schlechten Programmen die Daten der zuvor am der Stelle gespeicherten Werte der zuvor aufgerufenen Funktion.
Wieso sollten das "schlechte Programme" sein? Was sollen "gute Programme" an dieser Stelle anders machen?
Die sollten lokale Variablen initialisieren bevor sie diese nutzen.
Gast
#7756370
warum? Wenn sie im ersten Schritt beschrieben wird? Dann ist es doch wurscht Wenn ja, dann ja, wenn nicht, dann nicht. Dein Code-Auschnitt ist da wenig aussagekräftig. Die gcc-Warnung ist aber bekannt für häufigere Fehlwarnungen. Oliver
Das geht auch, dann wird sie eben "geschrieben" statt "initialisiert" vor dem ersten Auslesen. Allerdings kann der Compiler das manchmal nicht so ganz durchblicken und gibt dann doch die Warnung aus. Allerdings finde ich es sauberer, die Variable überhaupt erst dann zu deklarieren, wenn man auch einen Wert für sie hat, und sie dann eben damit zu initialisieren. Dann gibt es gar keinen Zeitraum, in welchem man die Variable versehentlich uninitialisiert nutzen kann.
Weil in "schlechten" Programmen die nicht initialisierte Variable z.B. als return zurückgegeben wird und in irgendwelchen if /else Gebirgen vergessen wurde ihr einen Wert zuzuweisen. Oder mit der uninitialisierten Variable gerechnet wird.
Weil das sonst ein Sicherheitsleck ist. Findige Nutzer könnten dann zurück ermitteln welche Daten in der vorher aufgerufenen Funktion dort standen, vielleicht das Passwort. Gute Programmiersprachen erlauben so einen uninitialisierten Mist gar nicht.
Ja, tatsächlich, die Warnung kommt erst nach "k++;", aber der Fehler ist "uint8_t k;". Erst mit "uint8_t k = 0;" funktioniert das Programm richtig. Dabei gibt es aber nur "int main(void)", sonst nichts, keine weiteren Funktionen.
Naja, bei
Was erwartest du soll dann in k drin stehen?
Jetzt weiß ich es nicht. Jetzt bin ich verwirrt.
Zur Präzisierung: Lokale Variablen, die nicht im Static Storage liegen (nicht zur Speicherklasse static gehören) werden nicht automatisch initialisiert falls die keinen Initializer haben. Daten im Static Storage werden immer initialisiert, egal ob lokal oder global, und auch dann, wenn sie keinen Initializer haben. Globale Variablen bekommen halt initial nen Zustand vorgegeben, der ist in dem Fall 0. Funktionen, die auf diese zugreifen, sind ja immer irgendwo nicht reentrant, weil abhängig von etwas, was außerhalb der Funktion liegt (wäre bei ner lokalen static-Variable aber auch so, siehe GetTickCount unter Win). Ich find's sehr begrüßenswert, dass der Compiler dich auf uninitialisierte Variablen hinweist - zusammen mit dem Prinzip 'Lokal geht vor global' könnte dann fast nen strukturiertes Programmieren mit definierten Funktions-Ein-/Ausgaben möglich werden :)
Hat man nicht immer. Wenn die Zuweisung beispielsweise in mehreren if-Zweigen erfolgt, dann hat man beim Anlegen noch keinen definierten Wert. Stur einfach immer einen Initialwert reinzuknallen kann Bugs verschleiern, die der Compiler ohne einen solchen Initialwert (als Warnung) aufdecken würde. Allerdings habe ich auch schon Situationen erlebt, in denen der Compiler nicht nachvollziehen konnte, dass eine Variable wirklich vor Benutzung auch gesetzt worden ist.
Dann poste halt Deinen Code. Entweder nutzt Du dort k und das Ergebnis ist (vermutlich) anders als erwartet. Oder Du nutzt k nicht, dann lass k weg.
eine andere Möglichkeit ist "static uint8_t k;". Dann wird es (wie eine globale Variable) vor dem ersten Aufruf mit 0 initialisiert, ist aber nur innerhalb der {} direkt verwendbar. Dabei gibt
Für den C-Compiler ist main nicht unbedingt eine besondere Funktion. main kann prinzipiell auch mehrfach aufgerufen werden. Es ist relativ egal, wo Du das Konstrukt verwendest. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|