while(1) oder for(;;)



  • Ich präferiere ersteres, bekomme aber ein warning C4127, da die Bedingung konstant ist. In der hilfe dazu steht, dass ich for(;;) verwenden soll, was aber wirklich nicht gerade ansehlich ist. Daher habe ich das murksige C4127 deaktiviert, dieses warnt jedoch auch bei if(0) etc., was vielleicht nützlich sein könnte(W4).



  • for(;;) ist tatsächlich die Endlosschleife. Das while(1) ist sozusagen ein Hack, der das gleiche bewirkt.
    Ich finde while(1) zwar auch schöner, aber for(;;) ist halt das was wirklich als Endlosschleife definiert ist.



  • erhehrerh schrieb:

    Daher habe ich das murksige C4127 deaktiviert, dieses warnt jedoch auch bei if(0) etc., was vielleicht nützlich sein könnte(W4).

    Läufst du denn Gefahr, in deinem Code if (0) zu schreiben? 😉

    Tippgeber schrieb:

    for(;;) ist tatsächlich die Endlosschleife. Das while(1) ist sozusagen ein Hack, der das gleiche bewirkt.

    Inwiefern ist das ein Hack? while prüft doch zu Beginn jedes Schleifendurchgangs, ob die Bedingung wahr ist, und bei Werten ungleich 0 ist das ja der Fall...?



  • #define ever ;;

    for(ever){};

    PS: Ja der ist alt und nicht mehr lustig 😃



  • Nexus schrieb:

    erhehrerh schrieb:

    Daher habe ich das murksige C4127 deaktiviert, dieses warnt jedoch auch bei if(0) etc., was vielleicht nützlich sein könnte(W4).

    Läufst du denn Gefahr, in deinem Code if (0) zu schreiben? 😉

    Tippgeber schrieb:

    for(;;) ist tatsächlich die Endlosschleife. Das while(1) ist sozusagen ein Hack, der das gleiche bewirkt.

    Inwiefern ist das ein Hack? while prüft doch zu Beginn jedes Schleifendurchgangs, ob die Bedingung wahr ist, und bei Werten ungleich 0 ist das ja der Fall...?

    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.
    Bei for(;;) wird nichts ausgewertet (es fehlt ja jegliche Bedingung), da es - wie gesagt - die Endlosschleife ist.



  • jetzt geht das wieder los



  • sothis_ schrieb:

    jetzt geht das wieder los

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

    Wie man sieht hat dies außerdem den Vorteil, dass man sich nicht über diverse Compilerwarnungen Sorgen machen muss und vor allem, wenn diese Warnungen auftauchen weiß, dass hier tatsächlich was schief laufen könnte und nicht nur eine der Endlosschleifen ist.

    Wie ich schon sagte finde ich eigentlich die while-Variante schöner, aber in C verwende ich immer for(;;), ich C++ oder anderen Sprachen würde ich ein while(true) in betracht ziehen, es sei denn der Compiler spuckt eine Warnung aus.



  • 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.


Anmelden zum Antworten