For Schleife in C89

#7635946
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
}
#7635949
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 :)

#7636207
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.

#7636229
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 */
#7636942
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.

#7638546
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

#7638558
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.

OP #7638572
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.

OP #7638706
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.

#7638733
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/?

#7638760
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
OP #7638761
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

#7638775
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.

#7638862
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.)

#7639090
Lesenswert?

Hallo, Sebastian W. schrieb im Beitrag #7639053:

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

#7639138
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"?

#7639174
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.

#7640868
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.

#7640928
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.

#7640937
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren