Forum: Compiler & IDEs For Schleife in C89


von C. W. (chefkoch)


Lesenswert?

Hallo,

kann mir jemand direkt an Beispielen den Unterschied zwischen C89 und 
C99 bei den For schleifen zeigen?

von Oliver S. (oliverso)


Lesenswert?

Es gibt keinen. Die von K&R definierte Variante funktioniert in allen 
Dialekten.

Alles andere ist zusätzlich.

Oliver

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

In C99 dürfen Variablen im ersten Teil des Schleifenkopfs definiert 
werden.


C99:
1
for (int i = 0; i < 10; i++)
2
{}

C89/C90:
1
int i;
2
3
for (i = 0; i < 10; i++)
4
{}

Das rührt daher, daß in C89/C90 die Variablendefinition auch nur zu 
Beginn eines Blocks erfolgen darf, d.h. das unmittelbar vor der 
Variablendefinition stehende Zeichen muss eine öffnende geschweifte 
Klammer sein.

C99:
1
int somefunction(void)
2
{
3
  dosomething();
4
5
  int y;
6
7
  y = dosomethingelse();
8
}

Die Definition von y ist so in C89/C90 nicht zulässig.

C89/C90:
1
int somefunction(void)
2
{
3
  int y;
4
5
  dosomething();
6
7
  y = dosomethingelse();
8
}

von NGC 5. (ngc5907)


Lesenswert?

Oliver S. schrieb:
> Es gibt keinen. Die von K&R definierte Variante funktioniert in allen
> Dialekten.

Klar, was K&R schrieben funktioniert in allen, es war aber nach dem 
Unterschied bei der for-loop zwischen C89 und C99 gefragt und da ist 
ganz klar in C99 die direkte Initialisierung der Laufvariablen in der 
for-loop erlaubt,
also
C89:
1
int i;
2
for (i = 0, i < 100, ...)

C99 erlaubt dann:
1
for (int i = 0, i < 100, ...)

Allgemein mussten in C89 alle Variablen am Anfang eines Blockes 
deklariert werden.

... und zu langsam :)

: Bearbeitet durch User
von C. W. (chefkoch)


Lesenswert?

Vielen Dank!

von Oliver S. (oliverso)


Lesenswert?

NGC 5. schrieb:
> es war aber nach dem
> Unterschied bei der for-loop zwischen C89 und C99 gefragt

Nein, war es nicht. Und den Rest hätten ein Blick in jedes C-Buch oder 
auch einfach in die Wikipedia erklärt.

Manche Fragen kann man mit nicht selber beantworten, aber andere schon.

Oliver

von Rolf M. (rmagnus)


Lesenswert?

Oliver S. schrieb:
> NGC 5. schrieb:
>> es war aber nach dem
>> Unterschied bei der for-loop zwischen C89 und C99 gefragt
>
> Nein, war es nicht.

Na sicher war das. Was denn sonnst?

> Und den Rest hätten ein Blick in jedes C-Buch oder auch einfach in die
> Wikipedia erklärt.

Warum hast du dann überhaupt versucht, es (falsch) zu erklären?

von Harald K. (kirnbichler)


Lesenswert?

NGC 5. schrieb:
> Klar, was K&R schrieben funktioniert in allen, es war aber nach dem
> Unterschied bei der for-loop zwischen C89 und C99 gefragt und da ist
> ganz klar in C99 die direkte Initialisierung der Laufvariablen in der
> for-loop erlaubt,

Das ist aber keine Eigenschaft der for-Schleife, sondern ein 
Abfallprodukt davon, daß in C99 Variablen überall definiert werden 
dürfen, statt nur am Blockanfang.

Die for-Schleife selbst ändert sich dadurch nicht, auch wenn es auf 
größere Distanz betrachtet so aussehen mag.

von (prx) A. K. (prx)


Lesenswert?

Harald K. schrieb:
> Das ist aber keine Eigenschaft der for-Schleife, sondern ein
> Abfallprodukt davon, daß in C99 Variablen überall definiert werden
> dürfen, statt nur am Blockanfang.

Wobei "for" in C99 in gewisser Weise selbst einen Blockanfang darstellt, 
denn die Sichtbarkeit solcher Variablen beschränkt sich auf das gesamte 
for-Statement. Die Deklaration folgt also so gesehen auch in C99 
unmittelbar auf einen Blockanfang.
1
for (int i = ...)
2
  printf("%d ", i);  /* OK */
3
printf("%d ", i);    /* Fehler, i ist unbekannt */
Das entspricht also in C89:
1
{
2
  int i;
3
  for (i = ...)
4
    printf("%d ", i);  /* OK */
5
}
6
printf("%d ", i);      /* Fehler, i ist unbekannt */

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Harald K. schrieb:
> NGC 5. schrieb:
>> Klar, was K&R schrieben funktioniert in allen, es war aber nach dem
>> Unterschied bei der for-loop zwischen C89 und C99 gefragt und da ist
>> ganz klar in C99 die direkte Initialisierung der Laufvariablen in der
>> for-loop erlaubt,
>
> Das ist aber keine Eigenschaft der for-Schleife, sondern ein
> Abfallprodukt davon, daß in C99 Variablen überall definiert werden
> dürfen, statt nur am Blockanfang.

Nein, man kann sie nicht überall definieren. Zum Beispiel darf man sie 
auch beim for nur im ersten der drei Ausdrücke definieren, in den 
anderen beiden nicht und auch in einer if-Bedingung darf man das (im 
Gegensatz zu C++) nicht. Dass man sie nicht nur am Anfang eines Blocks 
definieren kann, ist natürlich Voraussetzung, aber dass man es innerhalb 
eines for-Schleifenkopfes auch kann, ist trotzdem nochmal ein eigenes 
Feature.

von Bauform B. (bauformb)


Lesenswert?

Aber was spricht gegen den C99-Stil? Warum mögen manche Leute das nicht 
und machen es wieder rückgängig (vor 3 Wochen, in 2024!)

https://gitlab.com/chrony/chrony/-/commit/7fe98a83b867c1821b6f51c2ed8b3374825dfafd

von Oliver S. (oliverso)


Lesenswert?

Software, die auf so ziemlich allem laufen soll, was existiert, ist halt 
mit dem Einsatz "neumodischer" Sprachfeatures vorsichtig. Bis das mal in 
allen Compiler auf allen Plattformen verfügbar ist, und von allen 
IT-Verantwortlichen zur Produktion freigegeben wurde, dauert es halt 
seine Zeit.

Da geht dann schon mal ein halbes Jahrhundert ins Land, bis das soweit 
ist ;)

Oliver

von Harald K. (kirnbichler)


Lesenswert?

Bauform B. schrieb:
> Aber was spricht gegen den C99-Stil? Warum mögen manche Leute das nicht
> und machen es wieder rückgängig (vor 3 Wochen, in 2024!)

Es könnte sein, daß jemand noch mit einem älteren C-Compiler unterwegs 
ist.

Anekdote:
Das 2010 veröffentlichte "Microsoft Visual Studio 2010" kam mit einem 
C-Compiler, der nur C89/C90-kompatibel war.

Andere sind der Ansicht, daß in einem Block definierte Variablen am 
Blockbeginn zu definieren sind, weil sie so beim Lesen des Sourcecodes 
eher einen Eindruck davon gewinnen können, wie der Stackbedarf aussieht, 
als wenn Variablen quasi "irgendwo" im Code definiert werden.

Letztlich: Hier C89/C90-konform zu bleiben stellt keinen relevanten 
Nachteil dar, es muss nur der Code etwas anders strukturiert werden.

Das sieht bei anderen Dingen, die mit C99 oder später eingeführt wurden, 
ganz anders aus - "designated initializers" für Strukturen sind nur 
eines der Beispiele.

von C. W. (chefkoch)


Lesenswert?

Schon toll wieviel Beiträge zu einer so kurzen Frage gekommen sind. Es 
geht in meinem Fall wirklich um einen relativ singulären Compiler (CC65) 
der es halt einfach erfordert C nach C89 zu benutzen. Die Sinnhaftigkeit 
von C und 6502 sollte hier auch nicht weiter diskutiert werden.

von Harald K. (kirnbichler)


Lesenswert?

Ich vermute, daß Du den hier meinst:

https://github.com/cc65/cc65

Ist der besser als sdcc?

von Oliver S. (oliverso)


Lesenswert?

C. W. schrieb:
> Es
> geht in meinem Fall wirklich um einen relativ singulären Compiler (CC65)
> der es halt einfach erfordert C nach C89 zu benutzen.

Dieser sehr singuläre Compiler wird dir schon per Fehlermeldung 
mitteilen, wenn er etwas nicht kompilieren kann.

Oliver

von Philipp Klaus K. (pkk)


Lesenswert?

Harald K. schrieb:
> Ich vermute, daß Du den hier meinst:
>
> https://github.com/cc65/cc65
>
> Ist der besser als sdcc?

Als Compiler wohl nicht, aber dafür hat cc65 Laufzeitbibliotheken für 
einige bekannte 6502-basierte Systeme.

P.S.: Beim Z80 gab es früher eine ähnliche Situation sdcc vs. zcc/z88dk 
(inzwischen kann man dort die Bibliothek von z88dk auch mit sdcc 
nutzen).

: Bearbeitet durch User
von C. W. (chefkoch)


Lesenswert?

Und ich habe es bei CC65 hinbekommen das für mein 6502-System auf Basic 
RC6502 fertig brennbare HEX-Files rauskommen die laufen. Der 
6502-Support bei SDCC ist halt noch nicht so alt. Und wegen " Dieser 
sehr singuläre Compiler wird dir schon per Fehlermeldung mitteilen, wenn 
er etwas nicht kompilieren kann." ist die Fehlermeldung das er die 
Laufvariable der for-Schleife nicht findet nicht so aussagekräftig.

von Bauform B. (bauformb)


Lesenswert?

C. W. schrieb:
> Es geht in meinem Fall wirklich um einen relativ singulären Compiler
> (CC65) der es halt einfach erfordert C nach C89 zu benutzen.

OK, überredet, das ist ein Argument.

von Harald K. (kirnbichler)


Lesenswert?

C. W. schrieb:
> Und wegen " Dieser
> sehr singuläre Compiler wird dir schon per Fehlermeldung mitteilen, wenn
> er etwas nicht kompilieren kann." ist die Fehlermeldung das er die
> Laufvariable der for-Schleife nicht findet nicht so aussagekräftig.

Die Fehlermeldung wird wohl einen Hauch anders aussehen. "Can't find 
loop variable" halte ich für unwahrscheinlich.

Wie lautet die denn genau?

von Norbert (der_norbert)


Lesenswert?

1
int main(void) {
2
    for (int i=0; i < 10; i++) { }
3
    return 0;
4
}
1
$ cc65 main.c 
2
main.c(2): Error: Expression expected
3
main.c(2): Error: ';' expected
4
main.c(2): Error: Undefined symbol: 'i'
5
main.c(2): Error: ')' expected
6
main.c(2): Error: ';' expected
7
main.c(2): Error: Expression expected
8
main.c(2): Warning: Statement has no effect
9
main.c(2): Error: ';' expected

von C. W. (chefkoch)


Lesenswert?

Um es genau zu sagen:
1
#define RIOT (*(struct __riot*)0x8800)
2
3
#include <_riot.h>
4
#include <stdlib.h>
5
#include <stdint.h>
6
7
void main(){
8
    
9
    RIOT.swacnt=0xff;
10
    RIOT.swbcnt=0xff;
11
 
12
    while (1)
13
    {
14
        RIOT.swcha=0xff;
15
        
16
        for (int i=0;i<10;i++)
17
        {
18
          RIOT.swchb=0xff;
19
          RIOT.swchb=0x00;    
20
        }
21
        RIOT.swcha=0x00;
22
    }
23
    
24
25
}

erzeugt:
1
main.c(16): Error: Expression expected
2
main.c(16): Error: ';' expected
3
main.c(16): Error: Undefined symbol: 'i'
4
main.c(16): Error: ')' expected
5
main.c(16): Error: ';' expected
6
main.c(16): Error: Expression expected
7
main.c(17): Warning: Statement has no effect
8
main.c(17): Error: ';' expected
1
#define RIOT (*(struct __riot*)0x8800)
2
3
#include <_riot.h>
4
#include <stdlib.h>
5
#include <stdint.h>
6
7
void main(){
8
    
9
    RIOT.swacnt=0xff;
10
    RIOT.swbcnt=0xff;
11
 
12
    while (1)
13
    {
14
      int i;
15
        RIOT.swcha=0xff;
16
        
17
        for (i=0;i<10;i++)
18
        {
19
          RIOT.swchb=0xff;
20
          RIOT.swchb=0x00;    
21
        }
22
        RIOT.swcha=0x00;
23
    }
24
   
25
26
}

geht dann

von Harald K. (kirnbichler)


Lesenswert?

Norbert schrieb:
> main.c(2): Error: Expression expected

Da man Fehlermeldungen von C-Compilern immer in der Reihenfolge ihres 
Auftretens zu interpretieren hat, und das hier die erste ist, ist das 
Verhalten des Compilers also doch in Ordnung.

Der Compiler erwartet eine "expression", was "int i = 0" nicht ist.

von Norbert (der_norbert)


Lesenswert?

Harald K. schrieb:
> Norbert schrieb:
>> main.c(2): Error: Expression expected
>
> Da man Fehlermeldungen von C-Compilern immer in der Reihenfolge ihres
> Auftretens zu interpretieren hat, und das hier die erste ist, ist das
> Verhalten des Compilers also doch in Ordnung.
>
> Der Compiler erwartet eine "expression", was "int i = 0" nicht ist.

Danke. Allerdings mache ich das schon seit gut vierzig Jahren. ;-)
Als ich angefangen habe gab's noch nicht einmal C89.

von Harald K. (kirnbichler)


Lesenswert?

Norbert schrieb:
> Als ich angefangen habe gab's noch nicht einmal C89.

Mein Beileid. In C89 kann man auch heute noch sehr gut arbeiten, aber 
das, was es davor gab, das will man gründlichst vergessen haben. K&R-C 
war wirklich grässlich.

(Du siehst: Mir geht's ähnlich, ich habe meine ersten Schritte in C auch 
vor C89 gemacht, war dann aber sehr froh, mit "Turbo-C 2.0" auf dem PC 
einen der ersten (und dann auch noch brauchbaren) Compiler für das 
damals "ANSI-C" gennante bessere C zu bekommen.)

von Norbert (der_norbert)


Lesenswert?

Harald K. schrieb:
> Mein Beileid.

Ach das ging schon.
War auf einer Perkin Elmer unter Unix. Wir hatten ja sonst nichts… ;-)

Einmal ›X‹ am Ende, immer ›X‹ am Ende!

von Harald K. (kirnbichler)


Lesenswert?

Norbert schrieb:
> War auf einer Perkin Elmer unter Unix. Wir hatten ja sonst nichts… ;-)

Bei mir war es ein Echtzeitbetriebssystem von Microware (OS9/68k), und 
natürlich PCs mit x86. Im Realmode.

Hurks, mirsübel ... (speibrechreiherwürg)

Warum musste ich mich nur ausgerechnet daran erinnern? Warum nur?

von Bruno V. (bruno_v)


Lesenswert?

Norbert schrieb:
> Danke. Allerdings mache ich das schon seit gut vierzig Jahren. ;-)
> Als ich angefangen habe gab's noch nicht einmal C89.

Du nutztest Mitte der 80er nur Compiler, die das konten? C oder C++?

: Bearbeitet durch User
von Sebastian W. (wangnick)


Lesenswert?

C. W. schrieb:
1
> void main(){
2
>     ...
3
>     while (1)
4
>     {
5
>     ...
6
>     }
7
> }

Angesichts solch inkonsistenter Klammerungen in Laissez-Faire-Sprachen 
wie C lobe ich mir ja die Rigidität von Python, die auch 
Einrückungssünden gnadenlos abstraft.

LG, Sebastian

: Bearbeitet durch User
von Roland F. (rhf)


Lesenswert?

Hallo,
Sebastian W. schrieb:
> Angesichts solch inkonsistenter Klammerungen in Laissez-Faire-Sprachen
> wie C lobe ich mir ja die Rigidität von Python, die auch
> Einrückungssünden gnadenlos abstraft.

Ich zitiere mal Kernighan & Ritchie, "Programmieren in C", 2. Ausgabe 
ANSI-C
:
"Trotzdem bleibt C bei der grundsätzlichen Auffassung, das Programmierer 
wissen was sie tun; sie müssen nur ihre Absichten explizit kundtun."

Es wird einem eben nicht, wie bei Python, vorgeschrieben wie man einen 
Quelltext zu formatieren hat, im Gegenteil, man kann sich für einen von 
vielen Stilen entscheiden. Ich finde das gut.

rhf

von Rolf M. (rmagnus)


Lesenswert?

Roland F. schrieb:
> Es wird einem eben nicht, wie bei Python, vorgeschrieben wie man einen
> Quelltext zu formatieren hat, im Gegenteil, man kann sich für einen von
> vielen Stilen entscheiden. Ich finde das gut.

Also für die Einrückung fällt mir kein sinnvoller Stil ein, der in 
Python nicht auch möglich wäre. Oder meintest du das in der Art: 
"Natürlich mache ich keine blödsinnigen Einrückungen, aber gut zu 
wissen, dass ich es könnte"?

von Norbert (der_norbert)


Lesenswert?

Bruno V. schrieb:
> Du nutztest Mitte der 80er nur Compiler, die das konten? C oder C++?

Nicht ganz klar was du wissen möchtest.

Wenn du mit ›das konnten‹ meintest: innerhalb eines for(…,…,…) einen 
integer einführen, natürlich/offensichtlich/selbstverständlich NICHT

zu C++: Hätte ich (und nicht nur ich) zur damaligen Zeit noch nicht 
einmal mit einer Kneifzange angefasst. Später, viel später ging's dann, 
noch viel später wurde es meiner rein subjektiven Meinung nach wieder 
schlimmer.

Jetzt benutze ich den Teil davon, der für die anfallenden Aufgaben 
wichtig und förderlich erscheint. Aber ich versuche keinesfalls das 
ganze Spektrum irgendwie zu nutzen, nur weil es eben da ist.

von Bruno V. (bruno_v)


Lesenswert?

Norbert schrieb:
> Wenn du mit ›das konnten‹ meintest: innerhalb eines for(…,…,…) einen
> integer einführen, natürlich/offensichtlich/selbstverständlich NICHT

Das war der Fehler in Deinem Beispiel und darauf wiesen Compiler und 
Harald hin. Auf was bezogen sich die 40 Jahre? Zumal Du sonst keinen 
Bezug zu Deinem Code geliefert hast.

von Norbert (der_norbert)


Lesenswert?

Jemand stellte die Frage wie der (Compiler) Fehler bei dem NICHT VON MIR 
stammenden Code-Segment lautet. Ich hab's kurz durchlaufen lassen und 
das Ergebnis gepostet.

Muss eigentlich alles zig-mal erklärt werden, oder kann man einfach mal 
den Verlauf sinnerfassend zur Kenntnis nehmen?

von Florian S. (sevenacids)


Lesenswert?

Auch wenn man mit der Formatierung der Klammern in C-basierten Sprachen 
viel Unübersicht erzeugen kann, die Struktur des Codes bleibt immer 
sichtbar und mehr oder weniger nachvollziehbar, und moderne Texteditoren 
können eine Wildwuchs-Formatierung mitterweile auch relativ 
unkompliziert beheben. Sprachen wie Python, bei der die Formatierung ein 
syntaktisch relevantes Sprachmittel ist, halte ich für problematisch, 
ganz grundsätzlich, unabhängig von den etwaigen Vor- und Nachteilen.

Aber wir waren ja hier bei C und dem Unterschied der for-Schleife 
zwischen C89 und C99. Das mit der Variablendefinition wusste ich bisher 
auch nicht, also wieder was gelernt.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Florian S. schrieb:
> Sprachen wie Python, bei der die Formatierung ein
> syntaktisch relevantes Sprachmittel ist, halte ich für problematisch,
> ganz grundsätzlich, unabhängig von den etwaigen Vor- und Nachteilen.

Der Satz ergibt ja nun keinen Sinn. Wie soll etwas unabhängig von Vor- 
und Nachteilen problematisch sein können? Wenn etwas Probleme 
verursacht, ist das doch automatisch ein Nachteil. Ich vermute, du 
meintest eigentlich, dass es dir rein subjektiv nicht gefällt, ohne dass 
du dafür eine Begründung hättest.

von Harald K. (kirnbichler)


Lesenswert?

Rolf M. schrieb:
> Wie soll etwas unabhängig von Vor-
> und Nachteilen problematisch sein können?

Ich nehme stark an, daß die "etwaigen Vor- und Nachteile" andere sein 
werden als die der Formatierung.

> (...) halte ich für problematisch, ganz grundsätzlich,
> unabhängig von den etwaigen Vor- und Nachteilen,
> die sie sonst noch haben mögen.

So würde ich den Satz interpretieren.

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.