2010-09-28 14 views

Respuesta

17

No diría mal, ya que dependerá de la elección personal. Mi política es que cuando hay una alternativa segura de tipos disponible en C++, úsalos ya que reducirá los errores en el código.

+0

¿Existe alguna documentación en línea donde pueda ver si una función es segura o no? –

+9

Si una función toma argumentos 'void *', o devuelve un resultado 'void *', entonces probablemente no sea seguro para tipos. Una función con una lista de argumentos variables (como 'printf') tampoco es segura en general. Cada vez que tenga que usar 'sizeof', probablemente el código no sea seguro. –

+1

@ vash47: No sé de ninguna publicación, pero puede usar las siguientes reglas como inicio. Las funciones variables (como printf y scanf) no son seguras, ya que el compilador no puede verificar que los argumentos variados tengan el tipo correcto (excepto en algunos casos especiales). Las macros son también menos seguras que las funciones en línea por la misma razón. –

15

Depende de qué funciones. Usar macros de define en C++ está muy mal visto, y por una buena razón. Casi siempre puede sustituir a un uso de una macro define con algo más fácil de mantener y seguro en C++ (plantillas, funciones en línea, etc.)

corrientes, por el contrario, están juzgado de algunas personas a ser muy lento y He visto una gran cantidad de código C++ válido y de alta calidad utilizando C FILE* con su anfitrión de funciones en su lugar.

Y otra cosa: con todo respeto a la plétora de posibilidades de formato de flujo, para cosas como simples impresiones de depuración, en mi humilde opinión no se puede superar la brevedad de printf y su cadena de formato.

+4

Depende del uso. Boost (aceptado universalmente como la mejor colección de bibliotecas para C++) utiliza macros en abundancia. –

+1

@Konrad, de acuerdo, aunque en cualquier guía respetuosa de C++ (como Effective C++) encontrará secciones completas dedicadas a por qué no se recomiendan las macros en C++. Además, ¿con qué estándares Boost es "el mejor"? ¿Diría que es mejor mediante la legibilidad de su implementación interna? –

+1

@Eli: Estaba hablando de la interfaz/funcionalidad, no de la implementación. Pero las macros son relevantes para eso: sin el uso de macros, Boost no podría proporcionar la interfaz que proporciona (en algunos casos) y sería mucho más difícil de depurar y mantener (en otros casos). Así que, aunque la implementación de Boost suele ser complicada (principalmente para abastecer a compiladores no conformes), las macros hacen que el código sea más fácil. ** Dicho esto **, realmente trato de evitar macros cuando sea posible (no los uso en absoluto en el código "normal"). –

8

Yo diría que los únicos que son realmente perjudiciales para mezclar son los emparejamientos entre malloc/free y new/delete.

De lo contrario, es realmente una cuestión de estilo ... y mientras que la C es compatible con la C++, ¿por qué querría mezclar los dos idiomas cuando C++ tiene todo lo que necesita sin caerse?

+7

printf le ofrece un mecanismo para formatear con precisión la salida, que no pude encontrar en cout. –

+3

@crypto - cout proporciona opciones de formato: http://www.arachnoid.com/cpptutor/student3.html –

+0

@crypto: escriba la suya: P – Mchl

0

No realmente, printf() es bastante más rápido que cout, y la biblioteca C++ iostream es bastante grande. Depende de la preferencia del usuario o del programa en sí (¿es necesario? Etc.). Además, scanf() ya no es apto para usar, prefiero fgets().

+3

Esto está mal: 'printf' es más rápido que' cout' es una leyenda urbana. Esto realmente depende de la implementación de la biblioteca estándar y de si las secuencias se almacenan en búfer o no (¡pero esto es lo mismo para las transmisiones C y C++!). 'printf' es ** no ** generalmente más rápido que' cout'. Incluso puede ser al revés. Además, 'fgets' y' scanf' son completamente diferentes ('scanf' does * formatted * input), y' fgets' se puede reemplazar por 'cin'. –

+1

bastante seguro de que se refería a fgets + sscanf – FastAl

2

Para las asignaciones, evitaría usar malloc/free por completo y me limitaré a usar new/delete.

0

Lo que se puede usar o no solo depende del compilador que se utilizará. Dado que usted está programando en C++, en mi opinión, para maximizar la compatibilidad, es mejor usar lo que proporciona C++ en lugar de c funciones a menos que no tenga otras opciones.

8

Definitivamente debe usar printf en lugar de cout. El último hace le permite hacer que la mayoría o todos los controles de formato printf lo permitan, pero lo hace en un stateful manera. Es decir. el modo de formateo actual se almacena como parte del objeto (global). Esto significa que el código incorrecto puede dejar cout en un estado en el que la salida subsiguiente se formatea erróneamente a menos que restablezca todo el formato cada vez que lo use. También causa estragos con el uso de hilos.

+0

Amén, ambos tenemos cicatrices de batalla por defender esta posición;) –

+2

+1, estoy completamente de acuerdo. Programación con efectos secundarios es malo, y aquí es un estándar de biblioteca que impone este mal comportamiento :-( –

+0

Por supuesto, todo el diseño de 'std :: cout' es que es un objeto que almacena estado. Su problema principal es su sin una copiadora, debería poder hacer una copia barata, establecer el estado, realizar una salida y luego descartar la copia sin afectar el original. – MSalters

7

Existen mejores soluciones para la mayoría de los casos, pero no para todos.

Por ejemplo, la gente usa con bastante frecuencia memcpy. Casi nunca haría eso (excepto en realmente código de bajo nivel). Siempre uso std::copy, incluso en punteros.

Lo mismo cuenta para las rutinas de entrada/salida.Pero es cierto que a veces, el estilo C printf es mucho más fácil de usar que cout (especialmente en el registro). Si Boost.Format no es una opción, entonces seguro, use C.

#define es una bestia completamente diferente. No es realmente una característica exclusiva de C, y hay muchos usos legítimos para ella en C++. (Sin embargo, muchos más que no lo son.)

Por supuesto que nunca lo utilizaría para definir constantes (eso es lo que es para const), ni a declarar funciones en línea (inline usar y plantillas!).

Por otro lado, a menudo es útil generar aserciones de depuración y generalmente como una herramienta de generación de código. Por ejemplo, soy una clase de pruebas de plantillas y sin un uso extenso de macros, esto sería un verdadero dolor en el * ss. Usar macros aquí no es bueno, pero ahorra literalmente miles de líneas de código.

0

Viniendo desde un ángulo ligeramente diferente, diría que es malo usar scanf en C, no importa C++. La entrada del usuario está muy lejos de ser variable para ser analizada de manera confiable con scanf.

-1

Acabo de publicar un comentario en otra respuesta, pero como no puedo ... C printf() es mejor que C++ 's iostream debido a la internacionalización. ¿Quieres traducir una cadena y poner el número incrustado en un lugar diferente? No puedo hacerlo con un ostream. La especificación de formato de printf() es un pequeño lenguaje en sí mismo, interpretado en tiempo de ejecución.

+1

Después de haber hecho la traducción de productos comerciales, considero que ninguno de los dos es realmente adecuado. La cadena "Tengo% d widgets" simplemente no se traduce. Incluso en inglés, necesita una segunda cadena, "Tengo% d widget" o "Tengo 1 widget" (como en inglés, ese es el único valor que tiene una forma diferente). En otros idiomas, tiene hasta 4 formularios. , dependiendo del valor de '% d'. Sin mencionar lo que sucede con las cadenas de formato cuando se las entregas a los traductores. Las posibilidades son muy altas. Al menos una de ellas romperá el '% d', p. cambiándolo a '% d'. – MSalters

Cuestiones relacionadas