webentwicklung-frage-antwort-db.com.de

Warum #if zum Ausblocken verwenden?

Reverse Engineering Code und ich bin irgendwie entsetzt über den Stil, aber ich wollte sicherstellen, dass es keinen guten Grund gibt, diese Dinge zu tun ...

Ist es nur mir oder ist das ein schrecklicher Codierstil?

if ( pwbuf ) sprintf(username,"%s",pwbuf->pw_name);
else sprintf(username,"%d",user_id);

Und warum Wrap-Code nicht zum Kompilieren in einem

#if 0
....
#endif

Anstelle von Kommentaren?


EDIT: Wie einige erklärt haben, liegt dies an der Möglichkeit zum Flummox/* * /, was ich nicht wusste.

Aber ich verstehe immer noch nicht, warum man nicht einfach die Werkzeuge der Programmierumgebung oder das Makro des bevorzugten Texteditors verwendet, um das Kommentieren mit "//" zu blockieren.

wäre das nicht VIEL einfacher und übersichtlicher, um visuell zu überspringen?


Bin ich nur unerfahren inCund mir fehlt, warum diese Dinge eine gute Idee sein könnten - oder gibt es keine Entschuldigung, und ich bin berechtigt, mich darüber irritiert zu fühlen, wie hässlich dieser Code ist?

28
Jason R. Mick

#if 0 wird häufig verwendet, wenn der entfernte Block Blockkommentare enthält

Ich sage nicht, dass es eine gute Praxis ist, aber ich sehe es oft.

Die einzeilige Flusssteuerung + Anweisung ist leicht genug zu verstehen, obwohl ich es persönlich meide (und die meisten Codierungsrichtlinien, unter denen ich gearbeitet habe, verbieten es).

Übrigens, ich würde den Titel wahrscheinlich so bearbeiten, dass er etwas nützlich ist. "Warum #if 0 anstelle von Blockkommentaren verwenden?"

Wenn Sie folgendes haben

#if 0
        silly();
        if(foo)
           bar();
        /* baz is a flumuxiation */
        baz = fib+3;
#endif

Wenn Sie den #if 0/#endif naiv durch /* */ ersetzen, wird der Kommentar unmittelbar nach der Flumuxiation enden, was zu einem Syntaxfehler führt, wenn Sie den */ anstelle des #endif oben drücken.

BEARBEITEN: Eine letzte Anmerkung, oft wird die #if 0-Syntax nur während der Entwicklung verwendet, insbesondere wenn Sie mehrere Versionen oder Abhängigkeiten oder Hardwareplattformen unterstützen müssen. Es ist nicht ungewöhnlich, dass der Code geändert wird 

#ifdef _COMPILED_WITHOUT_FEATURE_BAZ_
    much_code();
#endif

Mit einem zentralen Header, der Hunderte dieser #Definitionskonstanten definiert (oder nicht). Es ist nicht das Schönste auf der Welt, aber jedes Mal, wenn ich an einem anständigen Projekt gearbeitet habe, haben wir eine Kombination aus Laufzeitumschaltern, Konstanten für die Kompilierung (dies) und Kompilierungsentscheidungen für die Kompilierung verwendet (verwenden Sie einfach eine andere. cpp's abhängig von der Version) und gelegentliche Vorlagenlösung. Es hängt alles von den Details ab.

Während Sie der Entwickler sind, der das Ding überhaupt erst zum Laufen bringt, ist ... #if 0 ziemlich üblich, wenn Sie nicht sicher sind, ob der alte Code noch einen Wert hat.

36
jkerian

Kommentare sind Kommentare. Sie beschreiben den Code.

Code, der von der Kompilierung ausgeschlossen wird, ist Code, keine Kommentare. Es enthält häufig Kommentare, die den Code beschreiben, der nicht kompiliert wird.

Es sind zwei verschiedene Konzepte, und das Erzwingen der gleichen Syntax erscheint mir als Fehler.

19
Jeff Dege

Neben dem Problem, dass Kommentare im C-Stil nicht verschachtelt werden, hat das Deaktivieren von Codeblöcken mit #if 0 den Vorteil, dass sie reduziert werden können, wenn Sie einen Editor verwenden, der Code-Faltung unterstützt. Es ist auch sehr einfach in jedem Editor zu tun, während das Deaktivieren großer Codeblöcke mit Kommentaren im C++ - Stil ohne Editorunterstützung/Makros unhandlich sein kann.

Viele #if 0-Blöcke haben auch einen else-Block. Dies bietet eine einfache Möglichkeit, zwischen zwei Implementierungen/Algorithmen zu wechseln, und ist wahrscheinlich weniger fehleranfällig als das Auskommentieren eines Abschnitts und das Auskommentieren eines anderen Abschnitts. In diesem Fall ist es jedoch besser, etwas lesbareres wie #if DEBUG zu verwenden.

5
bta

Das ist ziemlich idiomatisches C genau dort. Ich sehe nicht, was daran so falsch ist. Es ist kein schönes Stück Code, aber es ist einfach zu lesen und es ist klar, was los ist und warum, auch ohne Kontext.

Die Variablennamen könnten besser sein und es wäre wahrscheinlich sicherer, snprintf oder vielleicht strncpy zu verwenden.

Wenn Sie denken, dass es besser sein könnte, wie würden Sie es vorziehen, wenn es besser wäre?

Ich könnte eine kleine Änderung vornehmen:

char username[32];
strncpy(username, 30, (pwbuf ? pwbuf->pw_name : user_id));
username[31] = '\0';
3

Was Blockkommentare mit // betrifft, kann ich mir vorstellen, dass Sie, falls Sie diesen Code in Ihr Quellcodeverwaltungssystem einchecken, das Schuldprotokoll als letzten Editor für diese Codezeilen anzeigen wird. Wahrscheinlich möchten Sie, dass der Kommentar Ihnen zugewiesen wird. Gleichzeitig wird Ihnen auch der Code selbst zugeschrieben. Sicher, Sie können zurückgehen und frühere Revisionen betrachten, wenn Sie das Schuldprotokoll für den "echten" Autor des Codes überprüfen müssen. Es würde jedoch Zeit sparen, wenn diese Informationen in der aktuellen Revision beibehalten werden.

3
Aaron Klotz

Offensichtlich hat jeder seine eigene Meinung zu so etwas. Also hier ist meins:

Ich würde niemals Code wie oben schreiben und weniger von jedem denken, der das getan hat. Ich kann nicht zählen, wie oft Leute denken, es sei in Ordnung, ohne Zielfernrohr wegzukommen und dann von ihm gebissen worden zu sein.

Noch schlimmer ist es, wenn die Steueranweisung in derselben Zeile wie der Codeblock steht. Das Fehlen von Einrückungen macht es schwieriger, die Flusskontrolle beim Lesen zu sehen. Nachdem Sie seit einigen Jahren programmiert haben, können Sie Code schnell und genau lesen und interpretieren, solange Sie sich auf bestimmte visuelle Hinweise verlassen können. Die Umgehung dieser Hinweise für "Sonderfälle" bedeutet, dass der Leser anhalten und einen doppelten Take machen muss, ohne dass es dafür einen guten Grund gibt.

Andererseits ist #if (0) während der Entwicklung in Ordnung, sollte aber entfernt werden, sobald Code "stabil" ist (oder zumindest 0 durch einen aussagekräftigen Präprozessorsymbolnamen ersetzt).

1

Woah da! Überreagieren Sie nicht ...

Ich würde es wegen der widersprüchlichen Abstände mehr als alles andere als unausgesprochen bezeichnen. Ich hatte Zeit, wo ich es besser fand, kurze Aussagen auf die gleiche Linie wie ihre IF zu setzen, obwohl diese Aussagen es dehnen.

Der Inline-Stil ist besser für vertikale Kürze ... er könnte leicht in 4 Zeilen unterteilt werden

if (pwbuf) 
  sprintf(username,"%s",pwbuf->pw_name); 
else 
  sprintf(username,"%d",user_id); 

Ich persönlich hasse den nächsten Stil, da er so langatmig ist, dass es schwierig ist, eine Datei zu überfliegen.

if (pwbuf) 
{
  sprintf(username,"%s",pwbuf->pw_name); 
}
else
{ 
  sprintf(username,"%d",user_id); 
}
0
smdrager

ich punti sopra indicati. Mache ich Monitor Sono Widescreen und Tutti, Al Giorno d'oggi, nicht mi dispiace

if (pwbuf) sprintf(username,"%s",pwbuf->pw_name);
else       sprintf(username,"%d",user_id);

Sembra sempre avere troppo spazio orizzontale und non abbastanza spazio verticale sul mio schermo!

Inoltre, se il blocco di codice ha già direttive per il preprocessore, non utilizzare #if 0; se il codice ha già commenti di blocco, non utilizzare /* */. Se ha già entrambi, o ricorrere a un editore che ha unctrl+/, per commentare molte righe. In caso contrario, sei pieno, elimina il codice a titolo definitivo!

0
Sanjay Manohar
if ( pwbuf ) sprintf(username,"%s",pwbuf->pw_name);
else sprintf(username,"%d",user_id);

Idiomatisch und prägnant. Wenn es mehr als zwei oder drei Mal berührt wurde, würde ich es anklammern und in die nächste Zeile bringen. Es ist nicht sehr wartungsfähig, wenn Sie Protokollinformationen oder andere Bedingungen hinzufügen.

#if 0
....
#endif

Es ist gut, Blöcke von Debug-Code einzuschalten oder nicht. Außerdem würden Kompilierungsfehler vermieden, die sich aus dem Versuch ergeben, einen Kommentar dieser Art zu blockieren:

/* line comment */
...
/* line comment again */

Da C-Block Kommentare nicht verschachteln.

0
Paul Nathan

Gelegentlich verwende ich den prägnanteren Stil, wenn er die Symmetrie des Codes unterstützt und die Zeilen nicht zu lang werden. Nehmen Sie das folgende Beispiel:

if (strcmp(s, "foo") == 0)
{
    bitmap = 0x00000001UL;
    bit = 0;
}
else if (strcmp(s, "bar") == 0)
{
    bitmap = 0x00000002UL;
    bit = 1;
}
else if (strcmp(s, "baz") == 0)
{
    bitmap = 0x00000003UL;
    bit = 2;
}
else if (strcmp(s, "qux") == 0)
{
    bitmap = 0x00000008UL;
    bit = 3;
}
else
{
    bitmap = 0;
    bit = -1;
}

und die prägnante Version:

if      (strcmp(s, "foo") == 0) { bitmap = 0x00000001UL; bit = 0;  }
else if (strcmp(s, "bar") == 0) { bitmap = 0x00000002UL; bit = 1;  }
else if (strcmp(s, "baz") == 0) { bitmap = 0x00000003UL; bit = 2;  }
else if (strcmp(s, "qux") == 0) { bitmap = 0x00000008UL; bit = 3;  }
else                            { bitmap = 0;            bit = -1; }

Es ist viel wahrscheinlicher, dass Bugs direkt in Ihr Gesicht springen.

Haftungsausschluss: Dieses Beispiel ist, wie gesagt, so konzipiert. Fühlen Sie sich frei, um die Verwendung von Strcmp, magischen Zahlen zu besprechen und ob ein tabellenbasierter Ansatz besser wäre. ;)

0
Secure