2010-09-02 18 views
28

código de ingeniería inversa y estoy un poco desconcertada por el estilo, pero quería asegurarse de que no hay una buena razón para hacer estas cosas ....¿Por qué usar #if 0 para comentar en bloque?

¿Soy yo o es este estilo horrible codificación

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

Y por qué código de envoltura no está destinado para su recopilación en un

#if 0 
.... 
#endif 

en lugar de comentarios?


EDIT: Así como algunos se explica más adelante, esto se debe a la posibilidad de flummox/* * /, que no me di cuenta.

Pero todavía no entiendo, ¿por qué no utilizar sus herramientas de programación o entorno macro del editor de texto favorito de bloquear comentar a cabo utilizando "//"

¿no sería mucho más sencillo y fácil de ¿Sabes saltear visualmente?


Am acabo sin experiencia en C y desaparecidos por qué estas cosas podrían ser una buena idea - o no hay ninguna excusa, y estoy justificado en sentirse irritado por lo feo que es el código?

+0

Lo he hecho antes, por alguna razón parece más claro. Nunca vi directivas de preprocesador para comentar el código. – Novikov

+0

@Novikov: He visto mucho el uso de directivas de preprocesador: D – BoltClock

+5

Es un poco feo, pero no completo * fugly *. Tiene la oportunidad de verse mucho mejor con gafas de cerveza ligeras a moderadas. – FrustratedWithFormsDesigner

Respuesta

37

#if 0 se utiliza con bastante frecuencia cuando el bloque eliminado contiene en bloques comentarios

No voy a decir que es una buena práctica, pero lo veo bastante a menudo.

La única línea de control de flujo + declaración es bastante fácil de entender, aunque personalmente evito (y la mayoría de las directrices de codificación que he trabajado bajo prohíbo)

Por cierto, probablemente editar el título a ser algo útil "¿Por qué utilizar #if 0 en lugar de comentarios en bloque"

Si has lo siguiente

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

Si ingenuamente reemplazar el #if 0/#endif con /* */ , Que hará que el comentario para terminar justo después flumuxiation, causando un error de sintaxis cuando se pulse el */ en el lugar de la anterior .. #endif

EDIT: Una nota final, a menudo la sintaxis #if 0 sólo se utiliza durante el desarrollo, particularmente si tiene que admitir múltiples versiones o dependencias o plataformas de hardware. No es inusual para el código para ser modificado para

#ifdef _COMPILED_WITHOUT_FEATURE_BAZ_ 
    much_code(); 
#endif 

con una cabecera centralizado definir (o no) cientos de esas constantes #define. No es la cosa más bonita del mundo, pero cada vez que he trabajado en un proyecto de tamaño decente, hemos utilizado alguna combinación de conmutadores de tiempo de ejecución, constantes de tiempo de compilación (esto), decisiones de compilación en tiempo de compilación (solo use diferentes). cpp depende de la versión) y la solución de plantilla ocasional. Todo depende de los detalles.

Si bien usted es el desarrollador que acaba de conseguir el trabajo en primer lugar, sin embargo ...#if 0 es bastante común si no está seguro de si el código anterior todavía tiene valor.

+0

¿Por qué no usar la buena moda antigua/* */??? ¿no es mucho MÁS claro que el código NUNCA se compilará cuando se visualice en un editor de texto/env de codificación? Parece que podría pasar fácilmente por alto esa etiqueta de preprocesador al escanear el código y pensar que se estaba compilando. –

+2

Un editor decente también descifrará el código #if 0'd, por lo que no es un gran problema. Editando con un ejemplo. – jkerian

+0

emacs no es un editor decente? Quiero decir que colorea el resto de mi c-text ... y colorea el código comentado ... –

3

Eso es bastante idiomático C allí mismo. No veo lo que está mal con eso. No es una pieza preciosa de código, pero es fácil de leer y es claro lo que está sucediendo y por qué, incluso sin contexto.

Los nombres de las variables podrían ser mejores, y probablemente sería más seguro usar snprintf o quizás strncpy.

Si crees que podría ser mejor, ¿cómo prefieres que se vea?

podría hacer un ligero cambio:

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

Supongo que preferiría ver la lógica de los demás en la próxima línea. Quiero decir que * entiendo * qué está haciendo, pero cuando primero veo "else" y luego lo que parece ser un condicional, mi cerebro se derrite un poco. Simplemente me molesta por alguna razón. De nuevo, quizás no sea lógico, por eso hice la pregunta ... ¿Tal vez tengo que volver a entrenar mi cerebro para pensar que es una buena idea? –

0

Woah allí! No reaccione de forma exagerada ...

Lo llamaría más descuidado para el espaciado más incoherente que cualquier otra cosa. He tenido tiempo en el que me pareció mejor hacer declaraciones cortas en la misma línea que su IF, aunque esas declaraciones lo están estirando.

El estilo en línea es mejor para mayor brevedad verticales ... podría fácilmente ser dividida en 4, más líneas

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

Personalmente me gusta el estilo siguiente, ya que por lo largo aliento, lo que hace difícil una descremada archivo.

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

La razón por la que se prefieren los corchetes adicionales es para evitar que alguien agregue una línea adicional más tarde y piense que será parte de la cláusula original. – Kenoyer130

+3

soportes son mucho más a prueba de futuro. –

+1

Si no nos enseñó algo ... http://stackoverflow.com/questions/21999473/apples-goto-fail-security-bug Ponía las llaves en la misma línea que 'if' y' else '(excepto el último) para reducir el número de líneas. – Interarticle

1

Obviamente, cada uno tiene su propia opinión sobre este tipo de cosas. Así que aquí está el mío:

Yo haría Nunca escriba el código como el anterior, y pensaría menos de alguien que lo hizo. No puedo contar la cantidad de veces que las personas piensan que está bien alejarse sin aparatos ortopédicos de alcance, y luego me muerden.

Poniendo la instrucción de control en la misma línea que el bloque de código es aún peor; la falta de sangría hace que sea más difícil ver el control de flujo mientras se lee. Una vez que ha estado codificando durante algunos años, se acostumbra a poder leer e interpretar el código de forma rápida y precisa, siempre que pueda confiar en ciertas señales visuales. Excluir estas señales para "casos especiales" significa que el lector tiene que detenerse y hacer una doble toma, sin una buena razón.

#if (0), por otro lado, está bien durante el desarrollo, pero se debe eliminar una vez que el código sea "estable" (o al menos reemplace 0 con algún nombre significativo de símbolo de preprocesador).

+0

Cuando codifiqué principalmente utilizando vi ejecutándose en una columna de 80 líneas 25, el terminal de clonación VT-100 marcado a 2400 baudios a BSD en un VAX, cada línea de pantalla era preciosa, por lo que 'if (a) b(); else c(); 'era mucho más aceptable para mí que dividirlo en cuatro líneas, y el hábito de soltar llaves en sus propias líneas era efectivamente impensable. Hoy, estoy más inclinado a ser generoso con el espacio en blanco vertical. Tienes que haber vivido dentro de las restricciones de una terminal real para apreciar los beneficios del estilo terser, sospecho. – RBerteig

+0

Aún escribo código como la muestra hoy solo si cabe completamente en una línea. En el momento en que se pliega a más de uno, necesita los frenos para evitar los riesgos obvios. En una línea, hay menos tentación de editar accidentalmente en declaraciones adicionales. – RBerteig

+0

Supongo que los nombres de los símbolos preprocesadores significativos están bien, siempre que estén explícitamente # undef'd. El problema con cosas como #ifdef NOT_THIS es que uno tiene que buscar a través de todos los archivos incluidos para ver si se define NOT_THIS. Si encuentra un #undef NOT_THIS, tiene una respuesta. Si no lo hace, se pregunta: "¿he buscado en todos los archivos?". No hay tales problemas con #if 0. – dmuir

0

puntos mencionados arriba. Pero siendo monitores de pantalla ancha y todos, en estos días, en cierto modo me no me importa

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

Siempre parece tener demasiado espacio horizontal, y no hay suficiente espacio vertical en mi pantalla!

Además, si el bloque de código ya tiene directivas de preprocesador, no use #if 0; si el código ya tiene comentarios de bloque, no use /* */. Si ya tiene ambas, recurrir a un editor que tiene un ctrl + /, para comentar un montón de líneas. Si no, estás lleno, elimina el código completamente!

+0

C pedantry alert: '//' son comentarios C++ ... –

+0

del estándar C (WG14 N1124 - ISO/IEC 9899: 1999; 6.4.9): "Excepto dentro de una constante de caracteres, un literal de cadena o un comentario , los personajes // introducen un comentario que incluye todos los caracteres multibyte hasta, pero sin incluir, el siguiente carácter de nueva línea ". – BillP3rd

+0

@Bill: Eso es C99. '//' no es parte de C89 o C90, aunque la mayoría de los compiladores lo aceptarán. –

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

Idiomático y conciso. Si se tocó más de 2 o 3 veces, lo colocaría entre corchetes y la siguiente línea. No es muy fácil de mantener si agrega información de registro u otras condiciones.

#if 0 
.... 
#endif 

Bueno para activar bloques de código de depuración o no. Además, se evitaría errores de compilación relacionados con tratar de bloquear el comentario este tipo de cosas a cabo:

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

Desde C bloques comentarios no anidan.

3

En cuanto a bloquear comentarios usando //, una razón por la que puedo pensar es que, si comprueba el código en su sistema de control de origen, el registro de fallos le mostrará como el último editor de esas líneas de código . Si bien es probable que desee que se le atribuyan los comentarios, al mismo tiempo, el código en sí también se le atribuye. Claro, puede volver atrás y mirar las revisiones previas si necesita verificar el registro de acusaciones para el autor "real" del código, pero ahorraría tiempo si conservara esa información en la revisión actual.

+1

Buen punto, pero al mismo tiempo, si está utilizando el control de código fuente, probablemente no debería comentar un código muerto. Probablemente deberías estar eliminándolo. –

4

Además del problema con los comentarios al estilo C que no anidan, la desactivación de bloques de código con #if 0 tiene la ventaja de que se puede contraer si está usando un editor que admita el plegado de código. También es muy fácil de hacer en cualquier editor, mientras que deshabilitar grandes bloques de código con comentarios al estilo de C++ puede ser difícil de manejar sin soporte/macros de editor.

También, muchos bloques #if 0 tienen un bloque else también. Esto proporciona una manera fácil de cambiar entre dos implementaciones/algoritmos, y es posiblemente menos propenso a errores que comentar en masa una sección y descomentar en masa otra. Sin embargo, sería mejor usar algo más legible como #if DEBUG en ese caso.

18

Los comentarios son comentarios. Ellos describen el código.

El código que se excluye de la compilación es código, no comentarios. A menudo incluirá comentarios, que describen el código que no se está compilando, por el momento/

Son dos conceptos distintos, y forzar la misma sintaxis me parece un error.

+2

+1 Esta es una buena racionalización. Usted hace un buen argumento para * siempre * usando el preprocesador para excluir el código. Claro que es un poco feo, pero el código muerto * debería * ser feo, ¿verdad? –

+0

Uno podría señalar que comentar un código que no se usa (no importa si se hace con comentarios o directivas de preprocesador) es un uso incorrecto porque esa es la tarea de un SCM.En caso de que quiera preservar una versión anterior de una paz de código (por ejemplo, para evitar cometer un error dos veces), este código definitivamente se convierte en un comentario estático (código mezclado con explicaciones útiles) que ya no tiene nada que ver con el código de tu programa Que dado que siempre sería un error excluir el código de la compilación. –

+0

No diré siempre, pero en general estoy de acuerdo contigo. Creo que la práctica correcta sería limpiar este tipo de desorden antes del check-in. –

0

De vez en cuando uso el estilo más conciso cuando admite la simetría del código y las líneas no son demasiado largas. Tomemos el siguiente ejemplo artificioso:

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; 
} 

y la versión concisa:

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; } 

Los errores son mucho más propensos a saltar directamente a la cara.

Descargo de responsabilidad: Este ejemplo es artificial, como he dicho. Siéntase libre de discutir el uso de strcmp, números mágicos y si un enfoque basado en tablas sería mejor. ;)

0

#if 0 ... #endif es bastante común en el código C anterior. La razón es que comentar con los comentarios del estilo C /* .... */ no funciona porque los comentarios no anidan.

Aunque es común, diría que no tiene cabida en el código moderno.La gente lo hacía en los viejos tiempos porque sus editores de texto no podían bloquear secciones grandes de comentarios automáticamente. Más relevante aún, no tenían el control de código fuente adecuado como lo hacemos ahora. No hay excusa para dejar comentarios o # ifdef'd en el código de producción.

Cuestiones relacionadas