Forum: PC-Programmierung Array - Summe berechnen in C


von Juergen72 (Gast)


Lesenswert?

 Array  02. Nov 2021 18:41  

Möchte ein beliebiges Array in C initialisieren mit 10 Feldern und 
daraus mittels einer For-Schleife die Summe berechnen. Doch mein Code 
liefert nur sehr hohe Zahlen und JEDES MAL ein Minus Zeichen davor... 
vlt kann sich den jemand mal anschauen?
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
int main(){
5
6
int i;
7
int iSumme = 0;
8
int iFeld[10];
9
10
11
for(i=0; i<10; i++)
12
{
13
14
iSumme += iFeld[i];
15
16
}
17
18
printf("\nDie Summe aller Elemente im Array ist: %d", iSumme);
19
20
}

von Oliver S. (oliverso)


Lesenswert?

Was erwartest du denn als Ergebnis? Dein "beliebiges" Feld enthält halt 
beliebige Werte, und dann kommt sowas raus.

Oliver

von Tw (Gast)


Lesenswert?

Na überlege mal selbst. Passt die Summe von 10 Integers unbedingt und in 
jedem Fall wieder in ein Integer?

von Stephan (Gast)


Lesenswert?

Und an welcher Stelle initialisierst Du int iFeld[10]?

von ,,, (Gast)


Angehängte Dateien:

Lesenswert?

> Und an welcher Stelle initialisierst Du int iFeld[10]?

Kaputter Compiler?

Die Summe aller Elemente im Array ist: 0
Was sonst.

von Stephan (Gast)


Lesenswert?

>Die Summe aller Elemente im Array ist: 0 Was sonst.

Und da bist Du (im vom TO gezeigten Fall) ganz sicher? ;)

von Oliver S. (oliverso)


Lesenswert?

,,, schrieb:
> Kaputter Compiler?

Deiner ist es auf jeden Fall…

Oliver

von Nop (Gast)


Lesenswert?

,,, schrieb:

> Die Summe aller Elemente im Array ist: 0

Das wäre der Fall, wenn das Array global oder static wäre. Ist es aber 
nicht, von daher liegt Undefined Behaviour vor (nicht initialisierte 
Variable lesen). Der Compiler darf jedes Ergebnis ausgeben oder auch 
gleich das ganze Programm wegoptimieren.

von Noch ein Vorschlag (Gast)


Lesenswert?

> Das wäre der Fall, wenn das Array global oder static wäre.

Wir haben uns angewöhnt - wenn die Zeile nicht eingerückt ist, handelt 
es sich um eine globale Variable. Solltest du auch so machen, damit 
jeder sofort sieht, wo das Problem liegt.

von Dirk B. (dirkb2)


Lesenswert?

Gib doch einfach mal in der Schleife den Inhalt von iFeld[i] aus.

von W.S. (Gast)


Lesenswert?

Nop schrieb:
> Der Compiler darf jedes Ergebnis ausgeben oder auch
> gleich das ganze Programm wegoptimieren.

Nun ja, 'uninitialisierte Variablen' ist als solches schon richtig. 
Allerdings ist es nicht die Aufgabe eines Conmpilers, irgendwelche 
Laufzeit-Ergebnisse auszugeben. Der Compiler erzeugt nur den zur 
Berechnung erforderlichen Maschinencode.

Ganz generell halte ich die Masche mit dem Nullen des RAM-Bereiches beim 
Kaltstart für eine gefährliche Sache, wenn man sich darauf verläßt. 
Weitaus sicherer ist man, wenn man sich an die Regel hält, daß man 
Variablen nur dann trauen kann, wenn man sie zuvor beschrieben hat.

W.S.

von W.S. (Gast)


Lesenswert?

Noch ein Vorschlag schrieb:
> Wir haben uns angewöhnt - wenn die Zeile nicht eingerückt ist, handelt
> es sich um eine globale Variable.

Angewohnheiten sind etwas, das die Sprachdefinition nicht berührt. Und 
hier braucht es nur eine kleine Umformatierung des Quelltextes, um den 
Sinn oder Unsinn von Angewohnheiten besser zu sehen:
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
int main()
5
{ int i;
6
  int iSumme = 0;
7
  int iFeld[10];
8
9
  for(i=0; i<10; i++) iSumme += iFeld[i];
10
  printf("\nDie Summe aller Elemente im Array ist: %d", iSumme);
11
}
Mit anderen Worten: alle Variablen liegen auf dem Stack und sind reinweg 
lokal. Und ob man nun eine Zeile direkt mit dem allerersten Text-Zeichen 
beginnt oder zuvor etwas an Leerzeichen hat, ist eigentlich egal. Soviel 
zu Angewohnheiten.

W.S.

von Oliver S. (oliverso)


Lesenswert?

W.S. schrieb:
> Ganz generell halte ich die Masche mit dem Nullen des RAM-Bereiches beim
> Kaltstart für eine gefährliche Sache, wenn man sich darauf verläßt.

Auch die Diskussion hatten wir schon öfter.

Ich halte es für eine sehr sinnvolle Sache, sich auf die zugesicherten 
Eigenschaften eines tools zu verlassen. Könnte man das nicht, müsste man 
ja um alle mögliche und unmöglichen Eventualitäten herumprogrammieren, 
was das ganze völlig sinnlos und unpraktikabel macht.

Sollte das tool, wie im hier besprochen Fall, ein ein C-Compiler sein, 
dann ist dafür klar definiert, welche "Ram-Bereiche" genullt werden, und 
welche nicht. Wenn der Compiler kein C-Compiler ist, dann gilt da 
natürlich nicht.

Oliver

von Gerald K. (geku)


Lesenswert?

Das Array muss vor der Benutzung initalisiert werden.

Beispiel:
1
memset(my_array,0,sizeof(my_array));

von Stephan (Gast)


Lesenswert?

Gerald K. schrieb:
> Das Array … initalisiert werden.

Soweit waren wir schon;)

von W.S. (Gast)


Lesenswert?

Oliver S. schrieb:
> Ich halte es für eine sehr sinnvolle Sache, sich auf die zugesicherten
> Eigenschaften eines tools zu verlassen. Könnte man das nicht, müsste man
> ja um alle mögliche und unmöglichen Eventualitäten herumprogrammieren,...

Nö, man müßte sich nur angewöhnen, sich nicht darauf zu verlassen, daß 
uninitialisierte Varablen immer auf Null gesetzt sind. Das ist keine 
unbillige Forderung.

Was daraus wird, wenn jemand sich versehentlich auch einmal auf diese 
Nullung bei lokalen Variablen auf dem Stack verläßt, sehen wir an diesem 
Thread.

W.S.

von Oliver S. (oliverso)


Lesenswert?

W.S. schrieb:
> Nö, man müßte sich nur angewöhnen, sich nicht darauf zu verlassen, daß
> uninitialisierte Varablen immer auf Null gesetzt sind. Das ist keine
> unbillige Forderung.

Es nicht nur eine unbillige, sondern eine sehr sinnvolle Forderung, daß 
man die Programmiersprache kennt, in der man programmiert. Alles andere 
ist Aluhutprogrammierung. Kann man machen, ist dann aber 
Privatvergnügen.

Oliver

von Mark B. (markbrandis)


Lesenswert?

W.S. schrieb:
> wenn jemand sich versehentlich auch einmal auf diese Nullung bei lokalen
> Variablen auf dem Stack verläßt

Eine solche gibt es aber laut C-Standard nicht. Man sollte schon die 
Eigenschaften derjenigen Sprache kennen, die man einsetzt. Und/oder man 
setzt Tools zur Codeanalyse ein, die solche Fehler erkennen können.

von Oliver S. (oliverso)


Lesenswert?

Nur so als Nachtrag:

..\main.c: In function 'main':
..\main.c:17:16: warning: 'iFeld' is used uninitialized 
[-Wuninitialized]

gcc 11

Oliver

von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
> Oliver S. schrieb:
>> Ich halte es für eine sehr sinnvolle Sache, sich auf die zugesicherten
>> Eigenschaften eines tools zu verlassen. Könnte man das nicht, müsste man
>> ja um alle mögliche und unmöglichen Eventualitäten herumprogrammieren,...
>
> Nö, man müßte sich nur angewöhnen, sich nicht darauf zu verlassen, daß
> uninitialisierte Varablen immer auf Null gesetzt sind.

Man sollte sich auch nicht darauf verlassen, dass Zuweisungen immer
ausgeführt werden. Deswegen sollte man statt
1
  a = b + 1;

schreiben:
1
  a = b + 1;
2
  a = b + 1;

Für sicherheitskritische Anwendungen reicht das aber noch nicht. Dort
schreibt man (bis SIL 2)
1
  a = b + 1;
2
  a = b + 1;
3
  a = b + 1;

und ab SIL 3
1
  a = b + 1;
2
  a = b + 1;
3
  for (i=0, i=0; i<1000; i1=i+1, i1=i+1, i=i1, i=i1) {
4
    a = b + 1;
5
    a = b + 1;
6
  }
7
  a = b + 1;
8
  a = b + 1;

Nur so kann man halbwegs sicher sein, dass das Ergebnis auch wirklich in
der Variable a ankommt.

;-)

: Bearbeitet durch Moderator
von W.S. (Gast)


Lesenswert?

Mark B. schrieb:
> Eine solche gibt es aber laut C-Standard nicht.

Das ist bekannt (auch mir!) und dennoch wurde es hier vergessen (jedoch 
NICHT von mir).
Nun, irgend etwas mal zu vergessen, ist menschlich. Also sollte man die 
Anzahl der zu erinnernden Regeln nicht unnötig hoch schrauben, sondern 
möglichst durch einfachere und wirkungsvollere Regeln ersetzen, die 
ihrerseits einen größeren Gültigkeitskreis besitzen. Eben dieses habe 
ich hier als bessere weil allgemeingültigere Regel vorgeschlagen.

Und wenn man diese Regel kennt und berücksichtigt, dann werden sowas wie 
generelle Nullung vor dem Programmstart schlichtweg überflüssig.

Das hat keineswegs mit Aluhut (=Scharlatanerie) zu tun, sondern nur mit 
sauberer Programmierung.

W.S.

von W.S. (Gast)


Lesenswert?

Yalu X. schrieb:
> Man sollte sich auch nicht darauf verlassen, dass Zuweisungen immer
> ausgeführt werden.

Was hast du denn kurz zuvor geraucht?

W.S.

von Nop (Gast)


Lesenswert?

W.S. schrieb:
> Der Compiler erzeugt nur den zur
> Berechnung erforderlichen Maschinencode.

Das mag bei Pascal stimmen, bei C liegst Du damit mal wieder daneben. C 
hat die as-if-Regel, unter der ein Compiler Code erzeugt, und die ist 
mit dafür verantwortlich, daß C-Code so performant ist.

> Ganz generell halte ich die Masche mit dem Nullen des RAM-Bereiches beim
> Kaltstart für eine gefährliche Sache, wenn man sich darauf verläßt.

Quatsch. Das ist nicht nur eine im C-Standard zugesicherte Eigenschaft, 
sondern der Compiler wird eine Null-Initialisierung bei globalen 
Variablen sowieso wegoptimieren - und sich nämlich darauf verlassen, daß 
der Startupcode eine zum C-Standard konforme Umgebung herstellt. Womit 
man wieder bei der Ausgangsbasis ist und sich auf den Startupcode 
verläßt.

von rbx (Gast)


Lesenswert?

W.S. schrieb:
> sondern
> möglichst durch einfachere und wirkungsvollere Regeln ersetzen

Also wenn man ein wenig Assembler kann, und gelegentlich vielleicht auch 
mal den Wunsch verspürt, so Leute wie den Gauß zu fragen, was er von 
C-Programmierung hält, bzw. mit anfangen kann, dann kann man bei einigen 
Code-Postings hier, und den darunter folgenden Kommentaren schon ein 
wenig schmunzeln..

von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
> Yalu X. schrieb:
>> Man sollte sich auch nicht darauf verlassen, dass Zuweisungen immer
>> ausgeführt werden.
>
> Was hast du denn kurz zuvor geraucht?

Vermutlich das gleiche Zeug wie du :D

Nein, ich habe mich von dir davon überzeugen lassen, einem Compiler
(bzw. einer Tool-Chain) nie zu trauen und werden künftig konsequent
danach handeln :)

Nein, ich glaube es wäre nicht sehr zielführend, von dir oder vom
c-hater irgendwelche Ratschläge zum Thema C-Programmierung anzunehmen.

von Klaus W. (mfgkw)


Lesenswert?

Aber ich nehme deinen Tip gerne an für die Firma.
Freue mich schon aufs nächste Review!

Wie macht man das eigentlich dann mit Vergleichen, wenn man die mehrfach 
testet? Solange testen, bis drei aufeinanderfolgende gleiches Ergebnis 
liefern? Auch, wenn darin Funktionen mit Nebeneffekten auftauchen?

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Klaus W. schrieb:
> Wie macht man das eigentlich dann mit Vergleichen, wenn man die mehrfach
> testet?

Ach, das ist einfach. Man schreibt:
1
if ( (a==b) && (b==a) ) 
2
{
3
    // Now a and b are truly equal
4
}

So kann man ganz sicher sein, dass der Vergleich korrekt ist.

;-)

von Nop (Gast)


Lesenswert?

Mark B. schrieb:

> Ach, das ist einfach.

Für höhere Sicherheitsanforderungen sollte da aber noch ein Voting rein, 
damit sogar W.S. sicher sein kann, daß seine Compiler funktionieren:
1
c = (a == b);
2
c += (a == b);
3
c += (a == b);
4
5
d = (a == b);
6
d += (a == b);
7
d += (a == b);
8
9
e = (a == b);
10
e += (a == b);
11
e += (a == b);
12
13
if (c>=2 && d>=2 && e>=2)
14
{
15
    // Now a and b are equal with redundant voting
16
}

von Oliver S. (oliverso)


Lesenswert?

Mark B. schrieb:
> Klaus W. schrieb:
>> Wie macht man das eigentlich dann mit Vergleichen, wenn man die mehrfach
>> testet?
>
> Ach, das ist einfach. Man schreibt:
> 1if ( (a==b) && (b==a) )
> 2{
> 3    // Now a and b are truly equal
> 4}
>
> So kann man ganz sicher sein, dass der Vergleich korrekt ist.
>
> ;-)

Da fehlt aber noch was
1
 
2
if ( (a==a) && (a==b) && (b==a) && (b==b) )

Erst jetzt kannst du wirklich sicher sein ;)

Oliver

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Sehr interessanter Thread!

Erinnert mich an eine meiner Abschlussprüfungen in Deutsch, bei der man 
aus einem 10 Zeilen Gedicht 20 Seiten Interpretation machen musste!

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Warum konnte man in diesem Thread nicht sachlich bleiben und den TO 
einfach nur darauf hinweisen, dass lokale Variablen, im Gegensatz zu 
globalen Variablen, nicht selbstständig genullt werden?

von Stephan (Gast)


Lesenswert?

Mark B. schrieb:
> Klaus W. schrieb:
>
>> Wie macht man das eigentlich dann mit Vergleichen, wenn man die mehrfach
>> testet?
>
> Ach, das ist einfach. Man schreibt:
> 1if ( (a==b) && (b==a) )
> 2{
> 3    // Now a and b are truly equal
> 4}
>
> So kann man ganz sicher sein, dass der Vergleich korrekt ist.
> ;-)

Ist:
1
if ( (a==b) && (b==a) ) 
2

atomar?
Wenn nicht, dann kann sich a oder b beim zweiten Teil der Prüfung 
verändert haben…

von mh (Gast)


Lesenswert?

Yalu X. schrieb:
> und ab SIL 3
>   a = b + 1;
>   a = b + 1;
>   for (i=0, i=0; i<1000; i1=i+1, i1=i+1, i=i1, i=i1) {
>     a = b + 1;
>     a = b + 1;
>   }
>   a = b + 1;
>   a = b + 1;
>
> Nur so kann man halbwegs sicher sein, dass das Ergebnis auch wirklich in
> der Variable a ankommt.

Ab SIL4 wird dann auch beachtet, dass nicht nur fraglich ist, ob die 
Zuweisung stattfindet, sondern dass sie fehlerhaft sein kann, wenn sie 
stattfindet. Stell dir vor, die voletzte (angweiesene) Zuweisung hat nen 
Bitfehler und die letzte (angewiesene) Zuweisung findet nicht statt...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

W.S. schrieb:
> Ganz generell halte ich die Masche mit dem Nullen des RAM-Bereiches beim
> Kaltstart für eine gefährliche Sache, wenn man sich darauf verläßt.

Offenbar bist Du traumatisiert von irgendeinem uralten C-Compiler aus 
dem letzten Jahrtausend (ich schätze mal 80er), der nur so mit Bugs 
gespickt war.

Vermutlich wars irgendein DOS-Programm, programmiert von Leuten, welche 
von C keine Ahnung hatten. Wie wir aus einem anderen Thread von Dir 
gelernt haben, hielt sich dieser olle Compiler noch nichtmals an die 
gebotene Reihenfolge bei AND- oder OR-verknüpften Statements, was damit 
Short-Circuit Evaluation schlicht unmöglich macht.

Aber ich kann Dich beruhigen:

Schon 1970 haben die ersten C-Compiler bzw. C-Runtime-Libs für die PDP 
11/70 unter UNIX dafür gesorgt, dass static- und globale Variablen mit 0 
initialisiert waren. Auch damals gab es schon die 
Short-Circuit-Evaluation, die Du immer noch nicht glauben magst.

Dein buggy DOS-C-Compiler aus dem letzten Jahrtausend existiert nicht 
mehr. Folglich gibt es auch keinen mehr, der globale oder static 
Variablen unitialisiert lässt.

Also höre einfach auf, immer wieder denselben Horror-Scheiß für bare 
Münze zu verkaufen, nur weil Dich Dein blöder DOS-C-Compiler in der 
Vergangenheit stark geschädigt hat. Das hilft hier keinem weiter. Du 
verbreitest schlicht Unwahrheiten.

: Bearbeitet durch Moderator
von Rolf M. (rmagnus)


Lesenswert?

mh schrieb:
> Yalu X. schrieb:
>> und ab SIL 3
>>   a = b + 1;
>>   a = b + 1;
>>   for (i=0, i=0; i<1000; i1=i+1, i1=i+1, i=i1, i=i1) {
>>     a = b + 1;
>>     a = b + 1;
>>   }
>>   a = b + 1;
>>   a = b + 1;
>>
>> Nur so kann man halbwegs sicher sein, dass das Ergebnis auch wirklich in
>> der Variable a ankommt.
>
> Ab SIL4 wird dann auch beachtet, dass nicht nur fraglich ist, ob die
> Zuweisung stattfindet, sondern dass sie fehlerhaft sein kann, wenn sie
> stattfindet. Stell dir vor, die voletzte (angweiesene) Zuweisung hat nen
> Bitfehler und die letzte (angewiesene) Zuweisung findet nicht statt...

Ihr solltet euch mal Java2k anschauen.
http://p-nand-q.com/programming/languages/java2k/

von Julius (Gast)


Lesenswert?

@Frank M.
Als Moderator ist dein Ton völlig unangemessen.

Ansonsten nennt sich es sich defensive Programmierung, wenn man sich 
nicht auf irgendwas verlässt. Schon der Compiler sollte eine Warnung 
ausgeben wenn du eine Variable nutzt, und vorher nicht gesetzt hast. 
Nicht so toll bei einer Saefty-Programmierung mit SIL Einstufung. 
Spätestens eine statische Codeanalyse wird darüber nicht hinwegsehen.

von Nop (Gast)


Lesenswert?

Julius schrieb:
> Schon der Compiler sollte eine Warnung
> ausgeben wenn du eine Variable nutzt, und vorher nicht gesetzt hast.

Das sollte er bei globalen und static-Variablen keineswegs tun, denn die 
sind immer initialisiert.

> Nicht so toll bei einer Saefty-Programmierung mit SIL Einstufung.

Doch, weil "Safety-Programmierung" nicht soviel bedeutet wie 
"Programmieren ohne Kenntnisse der Programmiersprache".

> Spätestens eine statische Codeanalyse wird darüber nicht hinwegsehen.

Doch, wird sie. Also, bei globalen und statischen Variablen.

Beitrag #6869515 wurde vom Autor gelöscht.
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Julius schrieb:
> @Frank M.
> Als Moderator ist dein Ton völlig unangemessen.

Moderatoren sind halt auch Forennutzer (und möchten das sein). Es gibt 
keinen Knopf, wo wir einstellen können "schreibe das als normaler Nutzer 
ohne Moderatoren-Bit".

> Ansonsten nennt sich es sich defensive Programmierung, wenn man sich
> nicht auf irgendwas verlässt.

Yalus Beitrag machte auf eine leicht spaßige, aber durchaus einen 
ernsten Hintergrund darlegende Weise dar, dass du dich zwangsläufig auf 
zugesicherte Eigenschaften verlassen können musst, ansonsten kannst du 
die Tools gleich wegwerfen. Genauso, wie du dich eben darauf verlassen 
können musst, dass der Compiler die zugesicherte Eigenschaft, dass 1 + 1 
= 2 ist, auch sauber umsetzt, musst du dich drauf verlassen können, dass 
eine zugesicherte Initialisierung auch erfolgt. Es wurde ebenfalls schon 
dargelegt, dass es völlig schnuppe ist, ob du bei statischen oder 
globalen Variablen noch explizit eine Initialisierung mit 0 einfügst: 
der erzeugte Code ist der gleiche, denn auch bei der expliziten 
Initialisierung verlässt sich der Compiler an dieser Stelle darauf, dass 
der Startup-Code das auf die Reihe bekommt. Genauso, wie er sich 
natürlich drauf verlässt, dass eine Initialisierung mit etwas anderem 
als 0 auf irgendeine Weise die Initialwerte in die Variablen 
transportiert.

Funktionieren diese Mechanismen mal nicht (was man im Embedded-Bereich 
dadurch verhunzen kann, dass Startup-Code und Linkerscript nicht 
zueinander passen, denn die beiden sind aufeinander angewiesen), dann 
ist man so oder so der Gelackmeierte.

> Schon der Compiler sollte eine Warnung
> ausgeben wenn du eine Variable nutzt, und vorher nicht gesetzt hast.

Macht er ja auch, an den Stellen, wo die Variable nicht ohnehin 
implizit initialisiert ist (also bei einer automatischen Variablen).

> Nicht so toll bei einer Saefty-Programmierung mit SIL Einstufung.
> Spätestens eine statische Codeanalyse wird darüber nicht hinwegsehen.

Selbst MISRA ist nicht so doof, und verlangt die explizite 
Initialisierung ausdrücklich nur für automatische Variablen. Genauer 
gesagt: es verlangt, dass sie nicht verwendet wird, bevor sie gesetzt 
worden ist.

Eine "ich initialisiere immer alle Variablen in der 
Definition"-Mentalität kann sich an dieser Stelle übrigens sogar 
kontraproduktiv auswirken: Nimm ein Stück Code, bei dessen Erstellung 
der Codefluss sichergestellt hat, dass eine bestimmte Variablen in jedem 
Falle einen Wert gesetzt bekommen hat (bspw. durch passende 
if/else-Konstrukte), bevor sie verwendet wird. Jetzt fügt jemand einen 
weiteren Zweig in den if/else-Konstrukt hinzu und vergisst, dass er dort 
dieser Variablen ebenfalls einen dedizierten Wert zuweisen müsste. Hast 
du an der Variablen keine Initialisierung gehabt, gibt es jetzt in der 
Codeanalyse eine Warnung. Hast du stur dagegen alle Variablen per "ich 
initialisiere immer alles mit 0" zugenagelt, gibt es keine Warnung, auch 
keine von einer anderweitigen statischen Codeanalyse, und du debuggst 
erstmal eine ganze Weile zur Laufzeit herum, warum alles nicht so 
funktioniert wie gedacht.

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Julius schrieb:
> Ansonsten nennt sich es sich defensive Programmierung, wenn man sich
> nicht auf irgendwas verlässt.

Ich bin ebenso ein Anhänger von defensiver Programmierung, aber ich 
verstehe darunter etwas ganz anderes.

Wenn man so programmiert, dass man dem Compiler nicht traut, nenne ich 
das nicht defensive Programmierung, sondern paranoide Programmierung. 
Mit paranoider Programmierung läuft man übrigens Gefahr, eigene 
Programmierfehler zu überdecken. Man schiebt dann zum Beispiel ein 
Phänomen, dass nur bei eingeschalteter Optimierung des Compilers zutage 
tritt, auf den Compiler.

In 99% aller Fälle ist dem aber nicht so, tatsächlich ist es ein 
Programmierfehler. Ein paranoider Programmierer fängt dann an, unsinnige 
Vorsichtsmaßnahmen zu ergreifen, bis der Fehler dann nicht mehr 
auftritt. Tatsächlich hat er aber damit nur die Symptome bekämpft und 
nicht den Fehler tatsächlich ausgemerzt.

Hier ein schönes Beispiel:

Unter https://mikrocontroller.bplaced.net/wordpress/?page_id=142 findet 
man die Formulierung:

"Ich habe Grundsätzlich die Compiler Optimierung AUS = “none”
und benutze auch nicht die Hardware-FPU"

Der Autor Uwe B. begündet das mit den Delay-Schleifen, die dann nicht 
mehr funktionieren. Tatsächlich habe ich festgestellt, dass bei 
eingeschalteter Optimierung ein Großteil seiner STM32-Library gar nicht 
mehr läuft, weil Uwe das Schlüsselwort "volatile" nicht kennt bzw. 
ungenügend einsetzt. So funktionieren dann interrupt-basierende Module 
seines Codes bei eingeschalteter Optmierung überhaupt nicht mehr - mal 
ganz abgesehen von den völlig unzulänglichen Delay-Schleifen.

Ja, man könnte es "defensive Programmierung" nennen, wenn man seinen 
Code nur ohne Optimizer zum Laufen bekommt. Ich halte diese Bezeichnung 
jedoch für unangebracht. Es ist für mich ein klarer Programmierfehler.

P.S.

Meine Definition von defensiver Programmierung: Die API meiner Module 
soweit absichern, dass sie auch mit den unsinnigsten Parametern 
zurechtkommt - auch wenn es nur die Ausgabe eines Fehlers ist.

Fazit:
1
Defensive Programmierung = Verlässlichkeit.
2
Paranoide Programmierung = Misstrauen gespickt mit Unsicherheit.

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hier noch ein klassisches Beispiel für paranoide Programmerung:
1
char buffer[16];
2
int global_variable;
3
4
int main ()
5
{
6
    ...
7
    strcpy (buffer, "Das ist ein gaaaanz langer Satz\n");
8
    ...
9
    if (global_variable == 0)
10
    {
11
        init_foo ();
12
    }
13
    else
14
    {
15
        foo ();
16
    }
17
    ...
18
}
Beim Testen stellt der Programmierer fest: "Huch, meine globale Variable 
ist ja gar nicht 0, denn init_foo() wird ja gar nicht ausgeführt!".

Er schiebt das auf den Compiler und meint, er müsse den Fehler mit einer 
expliziten Initialisierung von global_variable usw. at Runtime 
korrigieren.

Er schreibt also folgendes:
1
char buffer[16];
2
int global_variable;
3
4
static void
5
init_variables (void)
6
{
7
     strcpy (buffer, "Das ist ein gaaaanz langer Satz\n");
8
     global_variable = 0;
9
}
10
11
int main ()
12
{
13
    init_variables ();
14
    ...
15
    if (global_variable == 0)
16
    {
17
        init_foo ();
18
    }
19
    else
20
    {
21
        foo ();
22
    }
23
    ....
24
}
Tatsächlich hatte er in der ersten Version seines Programms einen 
klassischen Buffer-Overflow produziert - mit dem Nebeneffekt, dass er 
sich die Variable global_variable mit einem Wert ungleich 0 
überschrieben hat.

Mit der zweiten Version hat er seinen Buffer-Overflow zwar nicht 
ausgemerzt, er hat aber das Phänomen, dass die globale Variable nicht 0 
war, überdeckt. init_foo() wird nun aufgerufen und der Programmierer 
ist jetzt zufrieden.

Zu Unrecht, denn der Fehler ist nachwievor da! Und vielleicht merkt er 
viel später, dass der Inhalt seines Buffers durch seine paranoide 
Programmierung nun trunkiert wurde - vielleicht.

P.S.

strcpy() habe ich gewählt, um den Fehler im Beispiel verständlich zu 
machen. Tatsächlich sind Buffer-Overflows in der Praxis jedoch 
wesentlich subtiler.

: Bearbeitet durch Moderator
von Johannes S. (Gast)


Lesenswert?

Julius schrieb:
> Als Moderator ist dein Ton völlig unangemessen.

ich weiss nicht wie lange du hier schon mitliest, aber W.S. ist jemand 
der selber nur austeilt, eigene Fehler aber never ever zugibt.
Und er predigt ständig gefälligst das Datenblatt zu lesen, warum schaut 
er dann nicht mal in den C Standard? Anfänger werden mit seinen Tipps 
der 'Bauchgefühlprogrammierung' nur verdorben. Ich habe hier im Forum 
auch schon eine Menge dazugelernt, der Stil von dem ewig gestrigen ist 
aber nur abschreckend.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Julius schrieb:
> @Frank M.
> Als Moderator ist dein Ton völlig unangemessen.

Ich empfinde Franks Beitrag überhaupt nicht als unangemessen. Dass der
letzte Absatz etwas strenger formuliert ist, ist IMHO vor folgendem
Hintergrunds (den du vielleicht nicht kennst) durchaus akzeptabel:

W.S. hat in der Vergangenheit schlechte Erfahrungen mit einem C-Compiler
(dem Sozobon C für den Atari ST, also vor ca. 30 Jahren) gemacht, weil
dieser wohl massivste Bugs enthielt. Diese Bugs konnten mit ein paar
Work-Arounds umgangen werden, dazu zählen:

- die explizite Initialisierung sämtlicher statischer Variablen, selbst
  wenn der Wert 0 ist

- Verzicht auf "Kurzschlussauswertung" in logischen Ausdrücken,
  stattdessen Aufteilung der Ausdrücke in mehrere if-Konstrukte

W.S. behauptet nun seit Jahren immer und immer wieder, dass solche
Work-Arounds auch bei allen neueren C-Compilern (die diese Bugs nicht
haben, aber rein theoretisch haben könnten) zwingend anzuwenden seien.
Das ist natürlich Unsinn, führt aber durch die ständige Wiederholung bei
Programmieranfängern, die den Unsinn darin noch nicht erkennen, unnötig
zu Verunsicherungen.

Auf diesen Unsinn wurde W.S. schon vielfach hingewiesen, nicht nur von
den Moderatoren, sondern auch von vielen anderen Forenteilnehmern,
leider ohne Erfolg. Da ist es nicht verwunderlich, dass manch einer
(egal ob Moderator oder nicht) inzwischen zu etwas deutlicheren Worten
greift.

von Rolf M. (rmagnus)


Lesenswert?

Frank M. schrieb:
> Der Fehler ist nachwievor da! Und vielleicht merkt er viel später, dass
> der Inhalt seines Buffers trunkiert wurde - vielleicht

Das wird er wahrscheinlich schon feststellen, vermutet dann aber, dass 
der Compiler längere Strings nicht verarbeiten kann und baut dafür dann 
auch noch einen entsprechenden "work-around" in den Code ein.

von Johannes S. (Gast)


Lesenswert?

Julius schrieb:
> Als Moderator ist dein Ton völlig unangemessen.

Und das Frank hier als Programmierer schon einiges bewiesen hat siehst 
du an den Artikeln zu IRMP, Minos oder Steccy. Projeke, an denen W.S. 
übrigens auch massig rumgemäkelt hat.

Yalu X. schrieb:
> W.S. hat in der Vergangenheit schlechte Erfahrungen mit einem C-Compiler
> (dem Sozobon C für den Atari ST, also vor ca. 30 Jahren) gemacht

das ganze Tramiel OS war eine einzige Bug Sammlung, insbesondere das C 
SDK. Zu der Zeit hatte ich in einem Computershop gearbeitet und es gab 
tatsächlich einen Kunden der das da für viele DM gekauft hatte. Und es 
dann kurze Zeit später erbost zurückgegeben hatte weil unbenutzbar.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Das wird er wahrscheinlich schon feststellen, vermutet dann aber, dass
> der Compiler längere Strings nicht verarbeiten kann und baut dafür dann
> auch noch einen entsprechenden "work-around" in den Code ein.

Du hast den Nagel auf den Kopf getroffen! So kommt man von einem 
Fettnapf zum nächsten...

Man kann ja durchaus mal aus dem Nähkästchen plaudern, aber diese 
Work-Arounds altväterlich als Ratschläge zu verkaufen, die das "einzig 
Wahre" sind, geht mir mittlerweile gehörig auf die Hutschnur.

von Klaus W. (mfgkw)


Lesenswert?

Johannes S. schrieb:
> Yalu X. schrieb:
>> W.S. hat in der Vergangenheit schlechte Erfahrungen mit einem C-Compiler
>> (dem Sozobon C für den Atari ST, also vor ca. 30 Jahren) gemacht
>
> das ganze Tramiel OS war eine einzige Bug Sammlung, insbesondere das C
> SDK.

Zum Einen war damals "die andere Seite" auf der MSODS-Welt nicht viel 
solider, man darf das nicht mit dem heutigen Stand vergleichen, was 
Programmierumgebungen angeht.

Zum anderen gab es auch damals bessere und schlechtere Systeme.
Ich hatte auf Ataris weitgehend mit Compilern von Prospero zu tun 
(Fortran, C, Pascal). Und die waren sehr sauber gemacht.
Langweilig und bieder, aber zuverlässig.

Später auch mal PureC, auch das war brauchbar.

Wenn man natürlich damals schon die schlechten gesucht hat, konnte man 
die leicht finden.

(Daß TOS auch beim Kunden reifen durfte, ist natürlich wahr.
Aber ehrlich gesagt ist die MS-Welt heute noch in der einen Hälfte nicht 
reif geworden, und gleichzeitig in der anderen schon lange vermodert.)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Johannes S. schrieb:
> Und das Frank hier als Programmierer schon einiges bewiesen hat siehst
> du an den Artikeln zu IRMP, Minos oder Steccy. Projeke, an denen W.S.
> übrigens auch massig rumgemäkelt hat.

Man muss gerechterweise hier bemerken, dass W.S. sich eher über 
MINOS echauffiert hat. STECCY fand er soweit ganz okay, er hat 
sich sogar am STECCY-Thread konstruktiv beteiligt.

Das witzige ist, dass ich in STECCY viele Module aus dem von ihm 
stark beschimpften MINOS verwende - bis auf den NIC-Compiler und 
das NIC-Runtime-System eigentlich alles. Stattdessen wurde lediglich die 
Z80- und ZX-Spectrum-Hardware-Emulation von mir eingefügt. Hat er aber 
gar nicht gemerkt ;-)

Sorry, muss gerade laut lachen.

: Bearbeitet durch Moderator
von Joachim B. (jar)


Lesenswert?

Johannes S. schrieb:
> das ganze Tramiel OS war eine einzige Bug Sammlung

und das bessere KAOS wollte Tramiel nicht!
Von TOS 1.0 auf 1.4 war auch nur ein schlapper würgaround

Johannes S. schrieb:
> insbesondere das C
> SDK.

keine Ahnung welches das war, vielleicht gab es bessere, aber am Atari 
hatte ich daheim in C weiter an meine Prüfprogramme gefeilt die ich dann 
im C-Source auf Disk zum PC @work getragen hatte. Funktionierte immer 
gut, ausser das ich am Atari schon 2,5MB hatte und der PC regelmäßig 
auch mit EMM/QEMM 386 unter Speichermangel litt. Glücklicherweise hatten 
wir einen SoftwareWerkstudenten der die dicksten Routinen in ASM 
einstampfte.

von W.S. (Gast)


Lesenswert?

Nop schrieb:
> Das mag bei Pascal stimmen, bei C liegst Du damit mal wieder daneben.

Ach, dein Compiler übernimmt die Funktion der von dir geschriebenen 
Firmware??

Natürlich nicht. Der Compiler ist zuständig dafür, daß die Quelle 
korrekt in Maschinencode übersetzt wird. Die Berechnungen, die die 
erzeugte Firmware zur Laufzeit macht und die Ausgabe der Resultate ist 
Sache der von dir geschriebenen Firmware und nicht des Compilers.

Ist es derart schwer, dieses zu begreifen?

W.S.

von W.S. (Gast)


Lesenswert?

Yalu X. schrieb:
> - Verzicht auf "Kurzschlussauswertung" in logischen Ausdrücken,
>   stattdessen Aufteilung der Ausdrücke in mehrere if-Konstrukte

Du scheinst da etwas zu verwechseln. Die Abarbeitung von Ausdrücken 
strikt von links nach rechts ist etwas komplett anderes, als der Abbruch 
einer Boolean-Rechnung sobald das Ergenbis feststeht. Gerade sich auf 
das strikte Abarbeiten in einer bestimmten Richtung zu verlassen, ist 
bei Funktionen wie dem besagten 'match' eine gefährliche Sache, weil 
derartige Funktionen nicht nur ein Ergebnis liefern, sondern auch ihre 
Argumente verändern. Da kommt es wirklich drauf an, in welcher 
Reihenfolge die Aufrufe erfolgen. Und im dortigen Beispiel war es 
lediglich eine Zusammenfassung, die absolut unnötig war. So etwas sollte 
man sich lieber verkneifen. Man weiß nicht mit letzter Sicherheit, was 
bei höheren Optimierungsstufen damit passiert.

Genau so ist es mit dem Merken von ganzen Bergen von Regeln. Ich hatte 
da mal vor Jahren einen Effekt bei Chan's FAT-FS. Nach Wechseln der 
SD-Karte wurde diese nicht mehr erkannt. Grund war ein Bug, der daher 
rührte, daß der Autor sich an einer Stelle beim Initialisieren der Karte 
darauf verlassen hatte, daß irgend ein Zeiger oder andere Variable Null 
wären, was aber nur nach dem Systemstart so war. Ist schon lange her.

Also das Nullen des RAM mag für das Erkennen von nicht initialisierten 
Zeigern recht hilfreich sein, generell ist es jedoch besser, sich an die 
allgemeine Regel zu halten, daß man Variablen als uninitialisiert 
ansieht, solange man sie nicht beschrieben hat. Das ist eine 
universellere Regel als das Glauben, daß alles, was man noch nicht 
angefaßt hat, auch null zu sein hat. Was gelegentlich dabei herauskommt, 
haben wir gesehen, als zwei Leute ein uninitialisiertes Array auf dem 
Stack aufaddiert haben und zu völlig verschiedenen Resultaten gekommen 
sind.

W.S.

von W.S. (Gast)


Lesenswert?

Jörg W. schrieb:
> Macht er ja auch, an den Stellen, wo die Variable nicht ohnehin
> implizit initialisiert ist (also bei einer automatischen Variablen).

Jörg, du hackst mal wieder auf dem falschen Karnickel herum.

Bedenke mal, daß jeglicher Code in einem C Programm in irgend einer 
Funktion steht. Und die muß aufgerufen werden. Und so hat wohl jeglicher 
Programmteil seine Initialisierungsfunktion (z.B. UART27_Init(..) oder 
so ähnlich) und NIEMAND garantiert, daß eben so eine 
Initialisierungsfunktion nur ein einziges Mal nach dem Systemstart 
aufgerufen wird. Sowas ist bei Pascal anders, da hat jeder Unit die 
Möglichkeit, vor dem eigentlichen Programmstart irgend etwas zu tun, 
also etwas einmaliges quasi beim Kaltstart. Aber wir sind hier ja bei C 
und da gibt es sowas nicht.

Das alles ist auch keine Angelegenheit des Compilers und solche 
Kinder-Programme wie hier, die lediglich aus main() bestehen, sind in 
der Praxis gelinde gesagt unüblich. Also darf man beim Schreiben 
beispielsweise eines seriellen Treibers nicht darauf bauen, daß er nur 
ein einziges Mal nach Systemstart initialisiert wird. Und schon beim 2. 
Aufruf der Init-Funktion ist die ganze Diskussion um Nullung am 
Systemstart für die Katz. Da brauchen wir nicht mehr drauf 
herumzuhacken.

W.S.

von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
> Du scheinst da etwas zu verwechseln. Die Abarbeitung von Ausdrücken
> strikt von links nach rechts ist etwas komplett anderes, als der Abbruch
> einer Boolean-Rechnung sobald das Ergenbis feststeht.

Das letztere ist aber nur in Verbindung mit dem ersteren sinnvoll,
weswegen der C-Standard für die logischen Operatoren && und || beides
(definierte Reihenfolge und Abbruch, sobald das Ergebnis feststeht)
vorschreibt.

> Was gelegentlich dabei herauskommt, haben wir gesehen, als zwei Leute
> ein uninitialisiertes Array auf dem Stack aufaddiert haben und zu
> völlig verschiedenen Resultaten gekommen sind.

Niemand hier schlägt vor, Variablen uninitialisiert zu verwenden. Es
wurde lediglich davon abgeraten, Variablen doppelt zu initialisieren.

von Nop (Gast)


Lesenswert?

W.S. schrieb:
> Ist es derart schwer, dieses zu begreifen?

Du hättest es begreifen können, wenn Du den Rest des zitierten Postings 
sinnerfassend gelesen hättest - Stichwort as-if-Regel. Die Du natürlich 
weder kennst noch verstehst, weil Du kein C kannst.

von rbx (Gast)


Lesenswert?

nur um das ganze formal zu ergänzen, die Summenformel wäre eigentlich in 
etwa:

int n, summe;

summe = (n * (n+1))/ 2;

..wobei das durch 2 eigentlich keine FPU oder extra Klammer benötigt* ;)

Der Hintergrund ist:

1 2 3

3 2 1

4 + 4 + 4

usw.

Das nennt sich u.a. "der kleine Gauß":

https://de.wikipedia.org/wiki/Gau%C3%9Fsche_Summenformel

Und bei Asm könnte man alles auf ein Register addieren, z.B. (so grob)

add ax, bx

inc bx

loop

wobei bei der Variante mit loop beim PC noch ein Register als Zähler 
braucht, hier automagisch cx, ansonsten Vorzugsweise auch cx.

oder eben alles wichtige per Hexeditor o.ä. je nach Wunschwiederholung 
kopieren, das nennt man dann z.B.
https://de.wikipedia.org/wiki/Loop_unrolling

*jetzt ist aber noch immer die Formatfrage interessant.
Es werden ja traditionell beim Multiplizieren die Register ax und dx 
ergänzt. Bei 64 Bit kommt man so auf 128 Bit. Das ist schon ganz 
ordentlich. Für noch größere Werte kann man z.B. das Carry-Flag bemühen.

Spannend wäre diesbezüglich auch die Frage, wie geht der Shift (nach 
Rechts) über mehrere Register?

von Dirk B. (dirkb2)


Lesenswert?

rbx schrieb:
> nur um das ganze formal zu ergänzen, …

Das ist ja völlig am Thema vorbei.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

W.S. schrieb:
> Da kommt es wirklich drauf an, in welcher Reihenfolge die Aufrufe
> erfolgen.

Natürlich. Und deshalb ist es garantiert, dass die Evaluation der 
Ausdrücke immer von links nach rechts erfolgt.

Bei
1
if (A && B && C)
werden die Ausdrücke B und auch C NICHT mehr evaluiert, wenn bereits A 
false ist.

Etwaige Funktionsaufrufe, welche in B und C enthalten sind, werden dann 
auch NICHT ausgeführt. Das ist garantiert in C.

Nur so ist der tausendfach verwendete Code
1
if (ptr && *ptr)
überhaupt sinnvoll und absolut korrekt. Bei falscher Evaluationsrichtung 
würde man sofort einen Null-Pointer-Zugriff riskieren. Nur: So einen 
falsch arbeitenden Compiler, den Du da postulierst, gibt es gar nicht.

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

W.S. schrieb:
> Also darf man beim Schreiben beispielsweise eines seriellen Treibers
> nicht darauf bauen, daß er nur ein einziges Mal nach Systemstart
> initialisiert wird. Und schon beim 2. Aufruf der Init-Funktion ist die
> ganze Diskussion um Nullung am Systemstart für die Katz.

Überhaupt nicht, hier kann man das Feature, dass static Variablen bei 
Programmstart garantiert genullt sind, sogar direkt ausnutzen:
1
int serial_driver_init (void)
2
{
3
    static int already_called;
4
5
    if (! already_called)
6
    {
7
        ... // do initialization here!
8
        already_called = 1;
9
    }
10
}

Schon ist Deine Argumentation für die Katz. Diese init-Funktion kannst 
Du auch tausendmal aufrufen, wenn Du möchtest.

P.S.
Ich habe hier mit Absicht auf bool (bzw. true/false) verzichtet, um 
nicht noch ein Fass aufzumachen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

W.S. schrieb:
> Bedenke mal, daß jeglicher Code in einem C Programm in irgend einer
> Funktion steht.

Nein. Es gibt etwas, das vor allen Funktionen läuft, also vor main(), 
das ist der Startup-Code. In der objektorientierten Variante (die für 
dich bei Pascal wahrscheinlich der gedankliche Standard ist) werden 
natürlich außerdem noch die Konstruktoren statischer und globaler 
Objekte davor gerufen.

Erst dann kommt main() zum Zuge.

Klar, man kann natürlich auf jegliche globale und statische Variablen 
verzichten und versuchen, alles mit automatischen Variablen zu machen. 
Aber selbst Standard-Pascal hat globale Variablen, und 
nicht-Standard-Pascal hat üblicherweise auch statische Variablen. Sie 
werden einen Grund haben, sowas da mit eingeführt zu haben. ;-)

Yalu X. schrieb:
> weswegen der C-Standard für die logischen Operatoren && und || beides
> (definierte Reihenfolge und Abbruch, sobald das Ergebnis feststeht)
> vorschreibt

Hatte gestern gerade festgestellt, dass es einen Standard für "extended 
Pascal" gibt, der dafür dann eigens die Schlüsselwörter and_then und 
or_else erfunden hat.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Jörg W. schrieb:
> Hatte gestern gerade festgestellt, dass es einen Standard für "extended
> Pascal" gibt, der dafür dann eigens die Schlüsselwörter and_then und
> or_else erfunden hat.

Es gibt mit Gnu Pascal sogar einen (und wahrscheinlich den einzigen)
Compiler, der diesen Standard weitgehend implementiert. Aber Gnu Pascal
wird schon seit langem nicht mehr weiterentwickelt.

Für den FPC wurde 2017 die zukünftige Unterstützung von Extended Pascal
angekündigt. Immerhin gibt es dafür schon die Compiler-Direktive {$mode
extendedPascal}, aber noch nicht viel mehr. Auch and_then und or_else
werden noch nicht als Schlüsselwörter erkannt.

Aber W.S. würde diese neuen Operatoren sowieso nicht verwenden, sondern
darin einen Bug wittern, der unbedingt aroundgeworkt werden muss ;-)

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Ich muss (leider) W.S. in einem Ding recht geben ...

Globale und statische Variablen werden durch den Startup-Code 
initialisiert (nullen des BSS-Segments) und das ist nicht Teil des 
C-Standards.

Ansonsten finde ich die Diskussionen hier etwas mühsam - man kann sich 
in der Regel darauf verlassen, dass es funktioniert und wenn nicht, 
merkt man das auch schnell.

Ist vielleicht eine pragmatische Sicht eines Pragmatikers^^

von Rolf M. (rmagnus)


Lesenswert?

Mampf F. schrieb:
> Ich muss (leider) W.S. in einem Ding recht geben ...
>
> Globale und statische Variablen werden durch den Startup-Code
> initialisiert (nullen des BSS-Segments) und das ist nicht Teil des
> C-Standards.

Das ist falsch. Der C-Standard definiert zwar nicht, dass es einen 
Startup-Code oder ein BSS-Segemnt gibt, aber dass alle Variablen mit 
static storage duration implizit mit 0 initialisiert werden, sofern 
keine explizite Initialisierung vorliegt, ist sehr wohl im Standard 
definiert.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Das ist falsch. Der C-Standard definiert zwar nicht, dass es einen
> Startup-Code oder ein BSS-Segemnt gibt, aber dass alle Variablen mit
> static storage duration implizit mit 0 initialisiert werden, sofern
> keine explizite Initialisierung vorliegt, ist sehr wohl im Standard
> definiert.

Vielen Dank für die Korrektur!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Genauso, wie natürlich nicht mit 0 initialisierte globale und statische 
Objekte "irgendwoher" ihre Initialwerte bekommen müssen. Das wie ist 
auch hier nicht im Standard definiert.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.