BSDForen.de  

Zurück   BSDForen.de > Geekstuff > Programmieren

Antwort
 
Themen-Optionen Thema bewerten Ansicht
Alt 10.08.2012, 14:39   #1
dettus
Bicycle User
 
Benutzerbild von dettus
 
Registrierungsdatum: Aug 2004
Ort: nuernberg
Beiträge: 2.533
[C]unitialisierte variablen

herakles hatte in http://www.bsdforen.de/showthread.php?t=28112 den wunsch geaeussert einen neuen thread dazu aufzumachen. dort ist eine diskussion leicht off topic geworden.

ausgangspunkt war folgender code
Code:
int main(void){ int i; ++i %= 5; return 0; }
dieser fuehrte zu compiler-problemen, richtig(er) waere hier folgendes gewesen:
Code:
int main(void){ int i; ++i; i %= 5; return 0; }
bei der seitendiskussion ging es jetzt um die frage nach dem
Code:
int i;
was eine variable anlegt, diese aber nicht initalisiert. nun, wie schon im original erwaehnt, wird das ganze IMPLIZIT bei modernen compilern mit 0 inialisiert.

bei aeltern, und auch bei einigen selbstgestrickten im embedded bereich kann es allerdings vorkommen dass diese variable muell enthaelt.


wo kommt dieser muell her? antwort: vom stack. lokale variablen werden dort angelegt. nehmen wir mal an dass der stack im system bei 0x40001000 beginnt und in richtung kleiner werdende adresen waechst.

Code:
void func1() { float x; // @0x40000FFC int h; // @0x40000FF8 char y; // @0x40000FF7 short s; // @0x40000FF5 x=3.141519; } void func2() { int i; // @0x40000FFC int j; // @0x40000FF8 printf("%i\n",i); } int main(void) { func1(); func2(); }
wie man leicht sieht(tm) teilen sich nun float x und int i die gleiche speicheradresse. damit kann es vorkommen dass das printf() etwas muell ausgibt.
__________________
Computer science is not about using a computer. It is about unleashing its powers.
dettus ist offline   Mit Zitat antworten
Alt 10.08.2012, 16:19   #2
Kamikaze
Parasprite
 
Benutzerbild von Kamikaze
 
Registrierungsdatum: May 2005
Ort: /Earth/Europe/Germany/Karlsruhe
Beiträge: 9.636
Kamikaze eine Nachricht über ICQ schicken Kamikaze eine Nachricht über MSN schicken
8051 C-Compiler verwenden nur für Interrupts und reentrant Funktionen (Funktionen, die mehrmals aufgerufen werden können) einen Stack, push und pop sind dort sehr teuer.

Stattdessen wird ein Call-Tree angelegt und allen Variablen werden feste Speicheradressen zugewiesen. Durch den Call-Tree wird ermittelt welche Funktionen nie gleichzeitig aufgerufen werden, deren Variablen können den gleichen Speicher verwenden (so genanntes Overlaying).

Nicht initialsierte Variablen werden aber immer mit fetten Warnings von den Compilern quittiert.
__________________
[ bsdlogo 2.0 - Wiki - Ports - LibreOffice Pakete - PM schreiben - kamikaze@bsdforen.de ]
Disclaimer: My posts represent my perception. Errors and incompleteness are to be expected, I deny any responsibility to know everything.
Kamikaze ist offline   Mit Zitat antworten
Alt 10.08.2012, 17:42   #3
Crest
rm -rf /*
 
Registrierungsdatum: Jun 2008
Ort: Bremen
Beiträge: 1.079
Kamikaze: Wer freiwillig einen 8051 programmiert schiebt sich auch freiwillig glühende Eisen in den Arsch.
Crest ist offline   Mit Zitat antworten
Alt 10.08.2012, 18:54   #4
dettus
Bicycle User
 
Benutzerbild von dettus
 
Registrierungsdatum: Aug 2004
Ort: nuernberg
Beiträge: 2.533
@kamikaze: ah! wusste ich noch nicht. aber gut, das ist im prinzip ein "stack zur compilezeit". deckt sich mit meinem beispiel.

@crest: du, manchmal kann man sich seine umgebung nicht aussuchen. ein 8051 hat bei mir auf der arbeit schon ein problem geloest fuer das wir sonst 15000 euro fuer eine "professionellere" variante gezahlt haetten.
__________________
Computer science is not about using a computer. It is about unleashing its powers.
dettus ist offline   Mit Zitat antworten
Alt 10.08.2012, 20:49   #5
Kamikaze
Parasprite
 
Benutzerbild von Kamikaze
 
Registrierungsdatum: May 2005
Ort: /Earth/Europe/Germany/Karlsruhe
Beiträge: 9.636
Kamikaze eine Nachricht über ICQ schicken Kamikaze eine Nachricht über MSN schicken
Zitat:
Zitat von Crest Beitrag anzeigen
Kamikaze: Wer freiwillig einen 8051 programmiert schiebt sich auch freiwillig glühende Eisen in den Arsch.
Ich tue das Eine aber nicht das Andere. Damit bist du widerlegt.

Zitat:
Zitat von dettus Beitrag anzeigen
@kamikaze: ah! wusste ich noch nicht. aber gut, das ist im prinzip ein "stack zur compilezeit". deckt sich mit meinem beispiel.
Wie gesagt funktioniert es nicht mit Interrupts. Und beim Inline ASM muss man auch pushen und poppen, damit man nicht mit dem Compiler ins Gehege kommt.

Bei einem Interrupt sichern die Compiler alle Rn-Register (8 Stück), macht beim XC878 (den ich benutze) 64 Takte (~2.7µs) bloß zum pushen und poppen. Dafür gibt es Register-Bänke, je Interrupt Priorität braucht man eine weitere, damit sich die Interrupts nicht gegenseitig ins Gehege kommen können.
Natürlich verliert man mit jeder Register Bank 8 Byte Speicher - ein hoher Preis wenn man nur 256 Byte internen Speicher hat. Und die Register liegen auch noch in den 128 Byte direkt addressierbaren (und damit schnelleren) Speicher.
__________________
[ bsdlogo 2.0 - Wiki - Ports - LibreOffice Pakete - PM schreiben - kamikaze@bsdforen.de ]
Disclaimer: My posts represent my perception. Errors and incompleteness are to be expected, I deny any responsibility to know everything.
Kamikaze ist offline   Mit Zitat antworten
Alt 10.08.2012, 21:22   #6
Tron
Registered User
 
Registrierungsdatum: Apr 2004
Beiträge: 267
Zitat:
Zitat von dettus Beitrag anzeigen
Code:
int i;
was eine variable anlegt, diese aber nicht initalisiert. nun, wie schon im original erwaehnt, wird das ganze IMPLIZIT bei modernen compilern mit 0 inialisiert.
Dies ist schlicht falsch. Nicht initialisierte automatische (lokale) Variablen sind schlicht ... uninitialisiert. Kein Übersetzer treibt den Zusatzaufwand, diese mit 0 zu initialisieren. Falls das doch irgendeiner tut, dann darf man da sich schlicht nicht darauf verlassen.
Nur statische (globale) Variablen werden mit 0 (des entsprechenden Typs) initialisiert.
Manche Übersetzer nutzen uninitialisierte Werte auch (völlig von der Norm abgesegnet) zum Optimieren: undef + 1 -> undef, undef * 0 -> undef (sic), undef & 0 -> undef (sic).

Zitat:
wo kommt dieser muell her? antwort: vom stack. lokale variablen werden dort angelegt.
C kennt den Begriff "stack" nicht -- das Wort kommt in der gesamten Spezifikation nicht vor. Wie die Konzepte von C auf eine Maschine abgebildet werden, ist der Norm schlicht egal. Für diese zählt nur, dass die Verwendung uninitialisierter Variablen zu undefiniertem Verhalten führt. Durch welche Umstände der Maschinenabbildung da effektiv irgendein Wert reingelangt ist auch Sicht von C völlig egal: undefiniert ist undefiniert.

Zitat:
Code:
void func1() { float x; // @0x40000FFC int h; // @0x40000FF8 char y; // @0x40000FF7 short s; // @0x40000FF5 x=3.141519; }
Diese Sicht ist bestenfalls naiv. Lokale Variablen brauchen sich keineswegs im Keller befinden. Oder es können sich auch mehrere diesselbe Stelle teilen, falls sie nicht gleichzeitig verwendet werden. Selbst wenn die Werte von Variablen tatsächlich in den Keller ausgelagert werden (hier werden alle Variablen eh direkt verworfen), dann wird sich "s" höchstwahrscheinlich nicht an einer ungeraden Adresse befinden, sondern auf eine natürliche Adresse (sprich Vielfaches seiner Größe) ausgerichtet werden.
Tron ist offline   Mit Zitat antworten
Alt 10.08.2012, 23:53   #7
dettus
Bicycle User
 
Benutzerbild von dettus
 
Registrierungsdatum: Aug 2004
Ort: nuernberg
Beiträge: 2.533
Zitat:
Zitat von Tron Beitrag anzeigen
C kennt den Begriff "stack" nicht -- das Wort kommt in der gesamten Spezifikation nicht vor.
ist ja auch nicht c, sondern eine datenstruktur.

Zitat:
diese Sicht ist bestenfalls naiv. Lokale Variablen brauchen sich keineswegs im Keller befinden.
naiv mit sicherheit nicht. nur leichter um einen punkt anhand eines beispieles zu illustrieren. ob sie nun im speicher liegen, oder in registern... voellig wurst. darum gings nicht!

Zitat:
Oder es können sich auch mehrere diesselbe Stelle teilen, falls sie nicht gleichzeitig verwendet werden.
speichst du von compileroptimierungen? mit oder ohne "stack"?

Zitat:
dann wird sich "s" höchstwahrscheinlich nicht an einer ungeraden Adresse befinden.
du moechtest realistische werte? okay.
Code:
x@00007fffffffe81c h@00007fffffffe818 y@00007fffffffe817 s@00007fffffffe814 i@00007fffffffe81c j@00007fffffffe818
du sprichst hier von alignment. aber das tat wie gesagt bei meinem beispiel nichts zur sache.
__________________
Computer science is not about using a computer. It is about unleashing its powers.

Geändert von dettus (11.08.2012 um 00:07 Uhr).
dettus ist offline   Mit Zitat antworten
Alt 12.08.2012, 04:07   #8
Kamikaze
Parasprite
 
Benutzerbild von Kamikaze
 
Registrierungsdatum: May 2005
Ort: /Earth/Europe/Germany/Karlsruhe
Beiträge: 9.636
Kamikaze eine Nachricht über ICQ schicken Kamikaze eine Nachricht über MSN schicken
Oh, wir kriegen unseren eigenen BSDForen.de Bikeshed! Ob's jetzt wohl einen green IT Preis gewinnen?
__________________
[ bsdlogo 2.0 - Wiki - Ports - LibreOffice Pakete - PM schreiben - kamikaze@bsdforen.de ]
Disclaimer: My posts represent my perception. Errors and incompleteness are to be expected, I deny any responsibility to know everything.
Kamikaze ist offline   Mit Zitat antworten
Alt 12.08.2012, 06:25   #9
Tron
Registered User
 
Registrierungsdatum: Apr 2004
Beiträge: 267
Zitat:
Zitat von dettus Beitrag anzeigen
ist ja auch nicht c, sondern eine datenstruktur.
Nur den einzelnen Satz aus dem Kontext gerissen, hast du irgendwie recht. Mit Kontext ist diese Entgegnung sinnfrei.

Zitat:
naiv mit sicherheit nicht. nur leichter um einen punkt anhand eines beispieles zu illustrieren. ob sie nun im speicher liegen, oder in registern... voellig wurst. darum gings nicht!
Du versuchst etwas zu illustrieren, wo es nichts zu illustrieren gibt und vermittelst damit die gefährlich falsche Vorstellung, dass das Konzept "uninitialisierte Variable" inhärent an die Maschinenabbildung gebunden ist. Du hast geflissentlich den zentralen Aspekt meiner Aussage nicht zitiert: Die C-Spezifikation sagt, dass die Verwendung von uninitialisierten Variablen zu undefiniertem Verhalten führt. Werte für die Variable kommen nirgendwo her. Dort endet die Argumentationskette schlicht -- wie du auch richtig erkannt hast: "ob sie nun im speicher liegen, oder in registern... voellig wurst.". Was eine zufällige konkrete Implementierung bei der Maschinenabbildung als tatsächliches Verhalten zeigt ist aus der Sicht von C völlig egal. Das braucht nicht betrachtet werden, denn das Verhalten ist undefiniert! Es als gedankliches Bild zu verwenden ist sogar schädlich, denn das führt -- auch an anderen Stellen -- zu dem falschen Vorgehen "Was tut meine Maschine/mein Übersetzer hier?" statt die korrekte Frage "Was schreibt die Sprachspezifikation vor?" zu stellen.
Unterm Strich bleibt schlicht: Die Sprachspezifikation sagt, das Verhalten ist undefiniert, was der wichtige Aspekt ist. Was eine zufällige (und auch nicht genannte) Implementierung tut ist einfach egal.

Zitat:
speichst du von compileroptimierungen? mit oder ohne "stack"?
Deswegen sagte ich "naiv": Du gehst davon aus, dass es eine kanonische Maschinenabbildung mit Variablen im Keller gibt. Davon ist aber in der C-Spezifikation an keiner Stelle die Rede.

Zitat:
du moechtest realistische werte? okay.
Code:
x@00007fffffffe81c h@00007fffffffe818 y@00007fffffffe817 s@00007fffffffe814 i@00007fffffffe81c j@00007fffffffe818
du sprichst hier von alignment. aber das tat wie gesagt bei meinem beispiel nichts zur sache.
Das bestätigst meine Randbemerkung.
Tron ist offline   Mit Zitat antworten
Alt 12.08.2012, 07:42   #10
dettus
Bicycle User
 
Benutzerbild von dettus
 
Registrierungsdatum: Aug 2004
Ort: nuernberg
Beiträge: 2.533
also, in meinem beispiel kams vom stack.
hast du ein besseres?
__________________
Computer science is not about using a computer. It is about unleashing its powers.
dettus ist offline   Mit Zitat antworten
Alt 12.08.2012, 10:49   #11
Tron
Registered User
 
Registrierungsdatum: Apr 2004
Beiträge: 267
Zitat:
Zitat von dettus Beitrag anzeigen
also, in meinem beispiel kams vom stack.
hast du ein besseres?
Liest du eigentlich, was ich schreibe?

Nochmals mit Betonung:
Zitat:
Zitat von Tron
Du versuchst etwas zu illustrieren, wo es nichts zu illustrieren gibt und vermittelst damit die gefährlich falsche Vorstellung, dass das Konzept "uninitialisierte Variable" inhärent an die Maschinenabbildung gebunden ist. Du hast geflissentlich den zentralen Aspekt meiner Aussage nicht zitiert: Die C-Spezifikation sagt, dass die Verwendung von uninitialisierten Variablen zu undefiniertem Verhalten führt. Werte für die Variable kommen nirgendwo her. Dort endet die Argumentationskette schlicht -- wie du auch richtig erkannt hast: "ob sie nun im speicher liegen, oder in registern... voellig wurst.". Was eine zufällige konkrete Implementierung bei der Maschinenabbildung als tatsächliches Verhalten zeigt ist aus der Sicht von C völlig egal. Das braucht nicht betrachtet werden, denn das Verhalten ist undefiniert! Es als gedankliches Bild zu verwenden ist sogar schädlich, denn das führt -- auch an anderen Stellen -- zu dem falschen Vorgehen "Was tut meine Maschine/mein Übersetzer hier?" statt die korrekte Frage "Was schreibt die Sprachspezifikation vor?" zu stellen.
Tron ist offline   Mit Zitat antworten
Alt 12.08.2012, 16:34   #12
dettus
Bicycle User
 
Benutzerbild von dettus
 
Registrierungsdatum: Aug 2004
Ort: nuernberg
Beiträge: 2.533
Zitat:
Zitat von Tron Beitrag anzeigen
Liest du eigentlich, was ich schreibe?
oehm... liest du was ich schreibe? ich habe von muell geschrieben der in einem konkreten beispiel vom stack kommt. wovon schreibst du?
__________________
Computer science is not about using a computer. It is about unleashing its powers.
dettus ist offline   Mit Zitat antworten
Antwort


Dieses Thema betrachten zurzeit 1 Personen. (0 registrierte Benutzer und 1 Gäste)
 
Themen-Optionen
Ansicht Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist An.
Smileys sind An
[IMG] Code ist An
HTML-Code ist Aus
Gehe zu

Ähnliche Themen
Thema Erstellt von Forum Antworten Letzter Beitrag
[C] Variablen initialisieren Herakles Programmieren 10 10.11.2010 16:48
NO_??? Make Variablen FreeBSDuser FreeBSD - Installation 3 15.05.2007 19:11
lokale Variablen in awk Kamikaze Programmieren 4 17.07.2006 17:12
Variablen in make "unsetten" cirad FreeBSD - Anwendungen und Ports 2 14.12.2003 07:55
make / portinstall mehrere Variablen auf einmal übergeben? I.MC FreeBSD - Installation 2 22.11.2003 12:50


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:19 Uhr.


Powered by vBulletin (Deutsch)
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.