while(1) oder for(;;)



  • nun ich meinte eher damit, dass die letzte diskussion über endlosschleifen geschlossen wurde, weil sie in eine debatte über goto-code führte 😃



  • Tippgeber schrieb:

    Eigentlich gibts da nichts zu diskutieren, wer sich an die Vorgaben im Standard halten möchte nimmt for(;;) für eine Endlosschleife.

    Klär mich bitte mal auf: wo steht diese "Vorgabe"?



  • nimm 'for( ; ;)'. kein compiler meckert hier und es ist ausserdem ein zeichen weniger als 'while(1)'
    🙂



  • sothis_ schrieb:

    nun ich meinte eher damit, dass die letzte diskussion über endlosschleifen geschlossen wurde, weil sie in eine debatte über goto-code führte 😃

    Das ist jetzt interessant:
    Ich benutze nämlich if(0) um eine art error-handling mit goto zu machen, weil ich keinen weiteren do-while/etc. block haben wollte

    // Get the request
    	int len;
    	char* buf = recv_full(s, &len);
    	if(buf) {
    		// Variables
    		char *content, **ppLines = NULL, **current_line;
    		struct request_line rl = {0};
    
    		// Find the end of the request
    		content = strstr(buf, "\r\n\r\n");
    		if(!content)
    			goto BadRequest;
    		// Show the request
    		printf("Http: %s\n", buf);
    
    		// Split the lines
    		ppLines = split_lines(buf, content);
    		current_line = ppLines;
    		// Parse the request line
    		if(!parse_request_line(*current_line++, &rl))
    			goto BadRequest;
    		// Parse the message headers
    		while(*current_line) {
    			struct message_header mh = {0};
    			char* line = *current_line;
    			if(!parse_message_header(line, &mh)) {
    				// Ignore -->RFC2616
    				printf("Line ignored: %s\n", line);
    			}
    			current_line++;
    		}
    
    		// Bad request protected by if 0 <- BINGO!
    		if(0) {
    		BadRequest:
    			// Malformed headers
    			http_error(s, HTTP_ERROR_BAD_REQUEST);
    		}
    
    		// Cleanup
    		free(ppLines);
    		free(buf);
    	} else
    		closesocket(s);
    


  • tgedgr schrieb:

    Ich benutze nämlich if(0) um eine art error-handling mit goto zu machen, weil ich keinen weiteren do-while/etc. block haben wollte

    ruf doch doch anstatt deines gotos 'http_error(s, HTTP_ERROR_BAD_REQUEST);' und spring dann zu 'free(ppLines);'. dann brauchst du dieses sletsame 'if(0)' nicht.
    🙂



  • Ich gebe fricky nur ungern recht, aber in diesem Fall muss ich ihm zustimmen 😞

    Du hast hier keine Codeduplikation somit ist das goto und das komische if(0) nicht gerechtfertigt und du solltest die Aufrufe direkt an die Stelle packen und per goto zum Cleanup Code springen.



  • Ich hab jetzt umgebaut, und die warnung wieder aktiviert. Nun bekomm ich aber bei jeder nutzung von FD_SET diese warung um die ohren gehauen, da das makro mit do{} while(0) geschützt ist.

    Wo ist dann der sinn von dieser warnung, wenn es schon durch die standard header probleme gibt?



  • Tippgeber schrieb:

    Na, weil for(;;) die Endlosschleife ist. while(1) ist somit ein Hack, der das gleiche bewirkt, da 1 immer als wahr ausgewertet wird und somit die Schleife erneut durchlaufen wird.

    ich gehe davon aus, dass die meisten Compiler while(1) und for(;;) optimieren und zur selben Schleife kommen.

    int do_something(void)
    {
        int x = 8;
        return ++x;
    }   
    
    void while_schleife(void)
    {   
        while(1)
        {
            do_something();
        }   
    }   
    
    void for_schleife(void)
    {   
        for(;;)
        {
            do_something();
        }   
    }
    
    ~ $ gcc -dumpversion
    4.1.2
     ~ $ gcc es.c -c
     ~ $ objdump -d es.o 
    
    es.o:     file format elf32-i386
    
    Disassembly of section .text:
    
    00000000 <do_something>:
       0:   55                      push   %ebp
       1:   89 e5                   mov    %esp,%ebp
       3:   83 ec 10                sub    $0x10,%esp
       6:   c7 45 fc 08 00 00 00    movl   $0x8,-0x4(%ebp)
       d:   ff 45 fc                incl   -0x4(%ebp)
      10:   8b 45 fc                mov    -0x4(%ebp),%eax
      13:   c9                      leave  
      14:   c3                      ret    
    
    00000015 <while_schleife>:
      15:   55                      push   %ebp
      16:   89 e5                   mov    %esp,%ebp
      18:   e8 fc ff ff ff          call   19 <while_schleife+0x4>
      1d:   eb f9                   jmp    18 <while_schleife+0x3>
    
    0000001f <for_schleife>:
      1f:   55                      push   %ebp
      20:   89 e5                   mov    %esp,%ebp
      22:   e8 fc ff ff ff          call   23 <for_schleife+0x4>
      27:   eb f9                   jmp    22 <for_schleife+0x3>
    

    naja, mit -O2 gibt es einen kleinen Unterschied

    00000010 <while_schleife>:
      10:   55                      push   %ebp
      11:   89 e5                   mov    %esp,%ebp
      13:   eb fe                   jmp    13 <while_schleife+0x3>
      15:   8d 74 26 00             lea    0x0(%esi),%esi
      19:   8d bc 27 00 00 00 00    lea    0x0(%edi),%edi
    
    00000020 <for_schleife>:
      20:   55                      push   %ebp
      21:   89 e5                   mov    %esp,%ebp
      23:   eb fe                   jmp    23 <for_schleife+0x3>
    

    das sind aber nur 2 Befehle extra mit while(1). Ich denke, an der Performance wird sich trotzdem nichts ändern.



  • Mit welch einer Beharrlichkeit ihr die while(1)-Schleife in Schutz nehmen wollt, unglaublich.



  • Ja spinn ich?? schrieb:

    Mit welch einer Beharrlichkeit ihr die while(1)-Schleife in Schutz nehmen wollt, unglaublich.

    ich nehme nichts in Schutz. Ich gebe zu, dass ich while(1) für Endlosschleifen nehme, weil das für mich optisch/sematisch schneller klar ist, dass es sich um eine Endlosschleife handelt. Dann erzähl mir, was wirklich so "böse" oder falsch an der Verwendung von while(1) ggüber for(;;) ist? Ich hab kein Prolem, mich eines besseren belehren zu lassen.



  • supertux schrieb:

    Ich gebe zu, dass ich while(1) für Endlosschleifen nehme, weil das für mich optisch/sematisch schneller klar ist, dass es sich um eine Endlosschleife handelt.

    mich stören dabei die warnings des compilers. obwohl es beabsichtigt ist, sagt er mir 'condition always true'. da hat er ja recht. theoretisch könnte es ein fehler sein. daher nehme ich lieber for(;;). das schluckt er, ohne zu klagen.
    🙂



  • ich habe eine solche Warnung noch nie gesehen (zumidnest bei while(1), bei if(0) schon). Mit welchen Flags spuckt gcc diese Warnungen aus?



  • Vor allem stelle ich mir die Frage warum nicht auch bei for (;;) irgendwann eine Warnung kommen soll.



  • Tim schrieb:

    Vor allem stelle ich mir die Frage warum nicht auch bei for (;;) irgendwann eine Warnung kommen soll.

    Weil das die Definition der Endlosschleife ist - wie du dem C Standard entnehmen kannst.



  • Ich frage gerne nochmal: wo?



  • Tim schrieb:

    Vor allem stelle ich mir die Frage warum nicht auch bei for (;;) irgendwann eine Warnung kommen soll.

    Es wäre ja auch schade, wenn man keine Möglichkeit hätte, im Sinne des Compilers eine Endlosschleife zu notieren (Stichwort Mikrocontroller).

    P.S.: Übrigens könnte das der Thread mit den meisten 😉 - Smileys werden! 😉



  • _matze schrieb:

    Tim schrieb:

    Vor allem stelle ich mir die Frage warum nicht auch bei for (;;) irgendwann eine Warnung kommen soll.

    Es wäre ja auch schade, wenn man keine Möglichkeit hätte, im Sinne des Compilers eine Endlosschleife zu notieren (Stichwort Mikrocontroller).

    Erstens ist das keine Erklärung warum bei for(;;) keine Warnung kommen sollte, zweitens ist while(true) trotzdem genauso möglich und drittens, was sind diese ominösen "Mikrocontroller"?



  • Tim schrieb:

    Erstens ist das keine Erklärung warum bei for(;;) keine Warnung kommen sollte, zweitens ist while(true) trotzdem genauso möglich

    Na ja, warum ausgerechnet for(;;) in Ordnung sein soll und while(1) oder while(true) nicht, kann ich auch nicht nachvollziehen.

    Tim schrieb:

    und drittens, was sind diese ominösen "Mikrocontroller"?

    Wenn die Frage ernst gemeint ist: http://www.mikrocontroller.net/



  • Na wie oft denn noch for(;;) ist als ein Schlüsselwort für eine Endlosschleife zu verstehen oder warum meint ihr, dass das Ding ohne Fehler kompiliert? Das Weglassen der Bedingung bedeutet für den Compiler "hier will ich eine Schleife die nie abbricht" und das ist ja keineswegs offensichtlich, denn if() wird ja auch nicht als if(1) identifiziert. Das Verhalten ist durch den Standard geregelt.



  • supertux schrieb:

    ich habe eine solche Warnung noch nie gesehen (zumidnest bei while(1), bei if(0) schon). Mit welchen Flags spuckt gcc diese Warnungen aus?

    das ist'n metrowerks/freescale compiler. der ist ziemlich 'verbose' mit seinen warnings. bemerkt auch sowas wie if (a&0xff > 1000) <-- always false

    Tim schrieb:

    Vor allem stelle ich mir die Frage warum nicht auch bei for (;;) irgendwann eine Warnung kommen soll.

    weil kein vergleich drin steckt? bei for(;1==1;) motzt er jedenfalls wieder rum.
    🙂


Anmelden zum Antworten