Como desarrollador de Linux (lado del servidor), no sé dónde y por qué debería usar C ++.
Cuando voy por rendimiento, la primera y última opción es C.
Cuando el "rendimiento" no es el problema principal, los lenguajes de programación como Perl y Python serían buenas opciones.
Casi todas las aplicaciones de código abierto que conozco en esta área se han escrito en C, Perl, Python, script Bash, AWK o incluso PHP, pero nadie usa C ++.
No estoy discutiendo otras áreas como GUI o aplicaciones web, solo estoy hablando de Linux, CLI y demonios.
¿Hay alguna razón satisfactoria para usar C ++?
Respuestas:
Y ahí es donde debes retroceder. Ahora, no puedo, en absoluto , hablar por el desarrollo del servidor. Quizás no haya una razón convincente para preferir C ++ sobre las alternativas.
Pero, en general, la razón para usar C ++ en lugar de otros lenguajes es el rendimiento. La razón de esto es que C ++ ofrece un medio de abstracción que, a diferencia de todos los otros lenguajes que conozco, no tiene sobrecarga de rendimiento en tiempo de ejecución.
Esto permite escribir código muy eficiente que todavía tiene un nivel de abstracción muy alto.
Considere las abstracciones habituales: funciones virtuales, punteros de función y el lenguaje PIMPL. Todos estos se basan en la indirección que se resuelve en tiempo de ejecución mediante la aritmética del puntero. En otras palabras, incurre en un costo de rendimiento (por pequeño que sea).
C ++, por otro lado, ofrece un mecanismo de indirección que no conlleva ningún costo (rendimiento): plantillas. (Esta ventaja se paga con un (a veces enormemente) mayor tiempo de compilación).
Considere el ejemplo de una función de clasificación genérica.
En C, la función
qsort
toma un puntero de función que implementa la lógica por la cual los elementos se ordenan entre sí. LaArrays.sort
función de Java viene en varias variantes; uno de ellos clasifica objetos arbitrarios y requiereComparator
que se le pase un objeto que funcione de manera similar al puntero de función en C'sqsort
. Pero hay varias sobrecargas más para los tipos Java "nativos". Y cada uno de ellos tiene una copia propia delsort
método: una horrible duplicación de código.Java ilustra una dicotomía general aquí: o tiene duplicación de código o incurre en una sobrecarga de tiempo de ejecución.
En C ++, la
sort
función funciona de manera similarqsort
a C, con una diferencia pequeña pero fundamental: el comparador que se pasa a la función es un parámetro de plantilla . Eso significa que su llamada puede estar en línea . No es necesaria la indirección para comparar dos objetos. En un ciclo cerrado (como es el caso aquí), esto realmente puede hacer una diferencia sustancial.No es sorprendente que la
sort
función C ++ supere a las Csort
incluso si el algoritmo subyacente es el mismo. Esto es especialmente notable cuando la lógica de comparación real es barata.Ahora, no digo que C ++ sea a priori más eficiente que C (u otros lenguajes), ni que a priori ofrezca una mayor abstracción. Lo que sí ofrece es una abstracción que es muy alta e increíblemente barata al mismo tiempo, por lo que a menudo no es necesario elegir entre un código eficiente y reutilizable.
fuente
Arrays.sort
implementaciones de Java ). Solo tú pierdes la ventaja de la alta abstracción. Esta no es una desventaja específica de las plantillas, es una desventaja de la duplicación de código en general. Además, esto tiende a no importar, ya que en bucles cerrados, generalmente siempre se carga el mismo código.vector.push_back
paravector<int>
y otro paravector<float>
, pero mientras se trabaja con avector<int>
, hay pocas razones por las cuales elvector<float>
código estaría en el caché de instrucciones. Así que no veo cómo eso realmente importa. La creación de instancias de plantillas individuales está altamente optimizada y, por lo general, es más compacta que las implementaciones genéricas genéricasVeo demasiados programadores de C que odian C ++. Me llevó bastante tiempo (años) comprender lentamente qué es bueno y qué tiene de malo. Creo que la mejor manera de expresarlo es esta:
Menos código, sin gastos generales de tiempo de ejecución, más seguridad.
Cuanto menos código escribamos, mejor. Esto se aclara rápidamente en todos los ingenieros que luchan por la excelencia. Usted arregla un error en un lugar, no en muchos: expresa un algoritmo una vez y lo reutiliza en muchos lugares, etc. Los griegos incluso tienen un dicho, que se remonta a los antiguos espartanos: "decir algo en menos palabras, significa que eres sabio al respecto ". Y el hecho es que, cuando se usa correctamente , C ++ le permite expresarse en mucho menos código que C, sin costar la velocidad de tiempo de ejecución, a la vez que es más seguro (es decir, detecta más errores en tiempo de compilación) que C.
Aquí hay un ejemplo simplificado de mi renderizador : al interpolar valores de píxeles a través de la línea de exploración de un triángulo. Tengo que comenzar desde una coordenada X x1, y alcanzar una coordenada X x2 (desde el lado izquierdo al derecho de un triángulo). Y en cada paso, en cada píxel que paso, tengo que interpolar valores.
Cuando interpolo la luz ambiental que alcanza el píxel:
Cuando interpolo el color (llamado sombreado "Gouraud", donde los campos "rojo", "verde" y "azul" se interpolan por un valor de paso en cada píxel):
Cuando renderizo en el sombreado "Phong", ya no interpolo una intensidad (luz ambiental) o un color (rojo / verde / azul); interpolo un vector normal (nx, ny, nz) y en cada paso, tengo que volver -calcule la ecuación de iluminación, basada en el vector normal interpolado:
Ahora, el primer instinto de los programadores de C sería "diablos, escribir tres funciones que interpolan los valores y llamarlos según el modo establecido". En primer lugar, esto significa que tengo un problema de tipo: ¿con qué trabajo? ¿Mis píxeles son PixelDataAmbient? PixelDataGouraud? PixelDataPhong? Oh, espera, dice el eficiente programador C, ¡usa una unión!
..y luego, tienes una función ...
¿Sientes el caos deslizándose?
En primer lugar, un error tipográfico es todo lo que se necesita para bloquear mi código, ya que el compilador nunca me detendrá en la sección "Gouraud" de la función, para acceder realmente al ".a". (ambiente) valores. Un error no detectado por el sistema de tipo C (es decir, durante la compilación) significa un error que se manifiesta en tiempo de ejecución y requerirá depuración. ¿
left.a.green
Notó que estoy accediendo en el cálculo de "dgreen"? El compilador seguramente no te lo dijo.Luego, hay repetición en todas partes: el
for
bucle está allí tantas veces como haya modos de renderizado, seguimos haciendo "derecha menos izquierda dividida por pasos". Feo y propenso a errores. ¿Notó que comparo el uso de "i" en el bucle de Gouraud, cuando debería haber usado "j"? El compilador vuelve a estar en silencio.¿Qué pasa con el if / else / ladder para los modos? ¿Qué sucede si agrego un nuevo modo de renderizado en tres semanas? ¿Recordaré manejar el nuevo modo en todos los "if mode ==" en todo mi código?
Ahora compare la fealdad anterior, con este conjunto de estructuras C ++ y una función de plantilla:
Ahora mira esto. Ya no hacemos una sopa tipo union: tenemos tipos específicos para cada modo. Reutilizan sus cosas comunes (el campo "x") heredando de una clase base (
CommonPixelData
). Y la plantilla hace que el compilador CREE (es decir, genere código) las tres funciones diferentes que habríamos escrito nosotros en C, pero al mismo tiempo, ¡es muy estricto con los tipos!Nuestro bucle en la plantilla no puede funcionar y acceder a campos no válidos: el compilador ladrará si lo hacemos.
La plantilla realiza el trabajo común (el ciclo, que aumenta en "paso" cada vez), y puede hacerlo de una manera que simplemente NO PUEDE causar errores de tiempo de ejecución. La interpolación según el tipo (
AmbientPixelData
,GouraudPixelData
,PhongPixelData
) se realiza con laoperator+=()
que vamos a añadir en las estructuras - que básicamente dictan cómo se interpola cada tipo.¿Y ves lo que hicimos con WorkOnPixel <T>? ¿Queremos hacer un trabajo diferente por tipo? Simplemente llamamos una especialización de plantilla:
Es decir, la función a llamar se decide en función del tipo. ¡En tiempo de compilación!
Para reformularlo de nuevo:
WorkOnPixel
versiones, el código C ++ será MÁS RÁPIDO que C, porque el compilador incorporará laWorkOnPixel
especialización de plantilla específica del tipo ¡llamada!Menos código, sin gastos generales de tiempo de ejecución, más seguridad.
¿Significa esto que C ++ es el todo y el fin de todos los lenguajes? Por supuesto no. Todavía tiene que medir las compensaciones. Las personas ignorantes usarán C ++ cuando deberían haber escrito un script Bash / Perl / Python. Los novatos en C ++ que se desencadenan crearán clases anidadas profundas con herencia virtual múltiple antes de que pueda detenerlos y enviarlos a empacar. Utilizarán la metaprogramación Boost compleja antes de darse cuenta de que esto no es necesario. TODAVÍA usarán
char*
,strcmp
y macros, en lugar destd::string
y plantillas.Pero esto no dice nada más que ... mira con quién trabajas. No existe un lenguaje que lo proteja de usuarios incompetentes (no, ni siquiera Java).
Sigue estudiando y usando C ++, solo que no lo diseñes en exceso.
fuente
RAII por la victoria bebé.
En serio, la destrucción determinista en C ++ hace que el código sea mucho más claro y seguro sin sobrecarga alguna.
fuente
Plantillas y el STL. Cambia un poco de tiempo de compilación (y algunos mensajes de error potencialmente incomprensibles) por muchas herramientas útiles de abstracción y ahorro de trabajo, sin un impacto apreciable en el rendimiento en tiempo de ejecución (aunque la huella binaria puede ser un poco mayor).
Toma un tiempo entenderlo (me tomó un par de años antes de que hiciera clic), pero una vez que lo haces, la vida puede ser mucho más simple.
El procesamiento de texto en C ++ es un orden de magnitud menos doloroso que en C.
fuente
Si.
Si buscas eficiencia ejecutable, estás en C o C ++, así que me enfocaré en eso.
Incluso antes de que las plantillas fueran comunes, preferí usar C ++ sobre C para los tipos de ejecutables que discute a mediados de la década de 1990 por dos razones muy simples: polimorfismo de objetos y RAII .
He usado objetos polimórficos de C ++ para todo tipo de cosas interesantes. Por ejemplo, estaba trabajando en un sistema Linux incorporado con superposiciones de búfer de trama en CPU OMAP y XScale ARM. Las dos arquitecturas de hardware tienen características de superposición diferentes con API muy diferentes. Utilicé una clase base virtual "Overlay" común para exponer una vista idealizada de superposiciones, y luego escribí las clases "OmapOverlay" y "XScaleOverlay" que se instanciaron adecuadamente en tiempo de ejecución, dependiendo de la arquitectura en la que el código detectó que se estaba ejecutando.
Para simplificar demasiado, RAII es la idea de que asigna recursos conectados a un objeto durante el constructor del objeto, o tal vez más adelante en la vida útil del objeto, y los recursos se desasignan o liberan en el destructor del objeto. Eso es realmente bueno en C ++, porque los objetos que son variables automáticas se destruyen cuando salen del alcance. Para alguien que es igualmente competente en C y C ++, es mucho más fácil evitar las pérdidas de recursos y memoria en C ++. Tampoco verá mucho código C ++ con el meme C muy común de una etiqueta al final de una función que precede a un montón de llamadas a
free()
, y variasgoto
'' en el bloque de funciones saltando allí.Soy plenamente consciente de que puede hacer todas estas cosas con C: es mucho más trabajo, muchas más líneas de código, y lo que termina es mucho más feo y, a menudo, más difícil de entender. Hay un código de polimorfismo en todos los componentes internos del servidor X , y hombre, es fugoso y extraño y con frecuencia difícil de rastrear.
También trabajo mucho con las tecnologías de GNOME como GTK + y Clutter, todas las cuales están escritas en C usando el sistema GObject. GObject es como el sistema de objetos C ++ con la bonita cubierta quitada y todas las partes internas feas expuestas, y generalmente requiere media docena de líneas de código para hacer lo que haría una llamada al método C ++ de una línea. Actualmente estoy escribiendo algunos
ClutterActors
, y aunque las matemáticas son realmente interesantes, pienso constantemente: "Todo esto sería mucho más conciso y comprensible en C ++".También a menudo pienso: "Sabes, si estuviera escribiendo esto en C ++ en lugar de C, estaría en la sala viendo MythBusters con mi esposa en lugar de sentarme en mi oficina a las 9 PM".
fuente
C ++ es casi tan rápido como C (algunas cosas son más rápidas, otras más lentas) y ofrece mejores abstracciones y organización. Las clases funcionan de manera similar a los tipos primitivos, lo que permite utilizar grandes cantidades de código sin tener en cuenta. La sobrecarga del operador y las plantillas permiten escribir código que funciona mejor si cambian las representaciones de datos. Las excepciones pueden facilitar el manejo de errores. El compilador se puede usar para verificar más cosas en tiempo de compilación.
El precio que paga por esto es una curva de aprendizaje bastante desagradable, y es más fácil cometer errores sutiles que la mayoría de los otros idiomas con los que estoy familiarizado.
Por lo tanto, no puedo decir si valdría la pena que lo aprendas por lo que estás haciendo ahora. Ciertamente puede sobrevivir con combinaciones de Python o Perl y C, pero C ++ ofrece abstracción y rendimiento en un paquete difícil de acostumbrar.
fuente
restrict
se usa para hacer exclusiones de optimizaciones de alias, entonces, ¿cómo ayuda eso a acelerar las cosas ? ¿Y qué es un "parámetro de matriz estática"? ¿Y cómo afecta el "estilo" al rendimiento?T (&arr)[n]
ostd::array<T, n>
- tendrá que investigar esto más, ya que no hay mucha información disponible. Eso tiene sentido sobre los punteros inteligentes, definitivamente un buen ejemplo. Si codificamos en un campo de juego igual, no usaríamos excepciones, por lo que no se incurriría en ninguno de los costos potenciales ... sin embargo, sospecho que podría estar aludiendo a cómo, una vez que las bibliotecas de terceros entran en escena, muchas suposiciones están en riesgo.Considero C ++ como un lenguaje de la década de 1990, un lenguaje de una época pasada.
En aquel entonces era grande porque ofrecía construcciones y mecanismos de lenguaje de alto nivel a un costo menor en términos de rendimiento. Fue la herramienta universal para desarrollar todo, desde aplicaciones de libreta de direcciones hasta software de aviónica, y eso inspiró la locura OO. OOP resolvió el hambre y el SIDA, y sí, culpo a C ++ por tratar de lavarme el cerebro a fines de la década de 1990 cuando comencé a programar que no valía la pena aprender ningún lenguaje que no sea OO.
Ahora que el hardware ha avanzado tanto y han aparecido lenguajes modernos más nuevos, no veo que C ++ siga siendo una opción relevante para la mayoría de la programación de aplicaciones, excepto para el software computacionalmente intensivo donde todavía necesita algo de abstracción (juegos, simulaciones físicas, sistemas CAD, etc.) ) Incluso esto último se puede evitar si escribe un motor compacto y modular en C y tiene una lógica de aplicación de nivel superior delegada en un lenguaje de script ordenado.
Si necesita bajar al metal, use C sanamente, y cuando necesite ir a un nivel superior, hágalo en un lenguaje moderno que no anuncie la encapsulación mientras puede alterar libremente cada byte a través de un puntero.
fuente
Según Linus , no:
fuente
No creo que haya ninguna razón convincente para usar C ++. Si desea hacer programación OO, puede usar Python en su lugar y escribir las partes que necesitan un rendimiento rápido en C.
EDITAR: Hay otros lenguajes que interactúan bien con C, por lo que si no te gusta Python, hay alternativas.
fuente
¿Hay alguna razón para usar C ++? Ciertamente.
Algunas personas simplemente prefieren usar C ++ sobre otras opciones. Preguntar si hay una razón para usar C ++ es como preguntar por qué necesitamos tener cientos de sabores de helado. No a todos les gusta simplemente seguir con Vanilla.
Si los desarrolladores ya son muy competentes con C ++, la pregunta para ellos puede no ser "¿por qué usarlo?", Sino más bien "¿por qué no?". Parece que está sucediendo esta moda anti-C ++ en SO en este momento, pero lo creas o no, no todos se suscriben a eso. Algunas personas pueden simplemente preferir C ++ mejor que los otros lenguajes.
¿C ++ necesita ser usado para aplicaciones? Por supuesto no. Pero esta misma pregunta exacta también se puede hacer para cualquier otro idioma. Hay muy, muy pocos casos en los que un idioma en particular necesita ser usado para una aplicación.
fuente
Solo estoy cambiando de C a C ++, y creo que la ganancia es considerable, incluso si no necesita plantillas y POO.
fuente
Me sorprende que nadie haya mencionado esto todavía, pero C ++ nos presentó referencias que casi resuelven todos los problemas y dificultades de los punteros:
En lugar de:
Mucho más seguro y más fácil también ... y sin la sobrecarga de pasar por valor.
fuente
El dónde y el por qué generalmente serán:
Para la programación del lado del servidor, a menudo puede elegir entre una miríada de idiomas diferentes, compilados o interpretados. Por lo general, la elección del idioma depende de la plataforma en la que usted o su equipo serán más efectivos. O si aún no tiene un equipo, la disponibilidad de habilidades en el mercado.
En una nota al margen, realmente no entiendo decidir usar C / C ++ basado en el rendimiento (solo) ya que muchos lenguajes de secuencias de comandos son extensibles con C / C ++. Obtiene el beneficio de un lenguaje de desarrollo rápido junto con la capacidad de migrar las porciones lentas a extensiones C / C ++. Ciertamente, si está haciendo programación de sistemas donde cada operación cuenta es comprensible, pero en la mayoría del desarrollo de aplicaciones no lo entiendo.
fuente
C ++ vs Python vs Perl no se puede juzgar fácilmente. Depende del proyecto y los requisitos.
C ++ tiene un arsenal de utilidades de hace mucho tiempo, ejecutándose en muchas plataformas. Pero es doloroso comenzar a caminar a través de las corrientes simplemente pasando String a Integer y retrocediendo.
C ++, por otro lado, tiene un trato horrible con las dependencias de las bibliotecas. Una vez que compila algo en GCC X o VC ++ Y, no puede confiar en que el código se ejecutará en la próxima versión de esas herramientas. El mismo infierno está en Windows, el mismo infierno está en Unix también.
Perl, toma su poder del mundo Unix, pero especialmente como una herramienta de expresión regular. Esto es lo que se usa la mayor parte del tiempo. Junto con algunas herramientas bastante serias que incluso Java no puede hacerlo de manera normal (vea cómo cargar un archivo en un servidor web), Perl es "simplemente hágalo".
Python es un lenguaje fácil, flexible y dinámico. Tan fácil que puede enviar un número entero a una función, el script espera cadena, ¡pero puede obtener un resultado! Sin embargo, inesperado, pero un resultado. Por lo tanto, el programador debe ser muy cauteloso. IDLE ofrece algunas depuraciones, pero cuando ha conectado TELNET a un sistema, o ha ingresado SSH en tres niveles y desea encontrar su problema, el depurador no estará allí para estar junto a usted. Pero, puede hacer un gran trabajo matemático rápido.
Java es un ecosistema de palabras de moda, tecnologías extrañas y grandes palabras, y cuando solo desea cargar un archivo en el servidor web, descubre que solo puede hacerlo si el servidor tiene JSP . Si desea llamar a las bibliotecas del sistema o las funciones del sistema, como la supervisión, encontrará que tiene que cavar mucho. Y tal vez para llegar a JNI y OK ... piensas entonces ... "¿Por qué, Señor?"
Aparte de eso, Java es una gran herramienta para suites de negocios y multiproceso, me gustó mucho.
Rápido para hacer un programa y mostrarle a su CV "¡Oh, yo también conozco esa tecnología" y su aspirante a jefe, se sorprenderá! Aunque, la tecnología podría no ser tan necesaria ... (OK, amigos, odio el Spring Framework ...)
fuente
Lo que debe tener en cuenta al elegir un idioma es qué beneficio obtendrá al usarlo y cuánto tiempo llevará obtenerlo.
La idea principal entre lenguajes como Python y Perl es hacer más con menos tiempo de hombre, pero con más tiempo de CPU. De hecho, pasará más tiempo codificando un script de Python o Perl del que se ejecutará, pero entiendo mi punto.
La ventaja de C / C ++ es que son rápidos, pero a un costo de sintaxis y tipeo fuerte: debe hacer muchas cosas usted mismo para que la computadora no tenga que elegirlo en el momento de la compilación.
Cuando crea un código, algunas líneas se ejecutarán mucho más que otras, y esas líneas son las que plantean un problema. Por otro lado, todo el resto del código, en el que pasó mucho tiempo, se ejecuta con mucha menos frecuencia. Es posible que lo hayas escuchado, pero es la infame regla 80/20, y no podrás evitar esa regla.
La solución a este problema es usar un lenguaje más fácil (por más fácil quiero decir más amigable para el desarrollador: menos tipeo, interpretación perezosa, muchas rutinas y cosas preexistentes, etc.) para hacer todo su código.
Lo harás tan rápido en comparación con si lo hubieras hecho con C o C ++, habría tomado mucho más dolor de cerebro.
Su programa será lento, pero con un generador de perfiles, aísla la parte que se ejecuta el 80% del tiempo y las hace con C o C ++.
Al programar de esta manera, ahorró mucho tiempo y su programa es tan eficiente, tan rápido, tiene muchas menos posibilidades de perder memoria y ahorró tiempo.
Los lenguajes de script fueron diseñados para estar del lado del desarrollador, pero la optimización aún es posible. Por supuesto, puedes ser un mago de patrones de diseño o un vudú STL o incluso un guerrero cegador, y tal vez un monje haskell. Pero los idiomas nos hacen hablar con las computadoras, ¡los idiomas no están hechos para que seamos computadoras!
fuente
Linux? ¿Qué pasa con "Pascal orientado a objetos" o "D"?
Sugerencias:
fuente
¡El C ++ que uso se llama C con clases!
fuente
En realidad, hay una sola respuesta a todas las preguntas formadas de esta manera. La mejor razón para usar tecnología X en lugar de tecnología Y (donde X e Y están aproximadamente en el mismo nivel [como casi todos los lenguajes de programación contemporáneos lo están]) es porque ya conoces X y no sabes Y.
(pero después de que Haskell llegó, no ha habido ninguna razón para usar otra cosa)
fuente
No, en absoluto. Si no necesita el rendimiento y hay una biblioteca que puede usar el otro idioma, no se moleste con C / C ++. Solo lo hago hoy en día cuando me dirijo a sistemas integrados que no pueden (¿fácilmente?) Ejecutar idiomas. A veces uso C porque estoy escribiendo un complemento, pero realmente no.
Sin embargo, no usaría Python, Perl, etc. para evitar el uso de C. Mi preferencia es en realidad C #, porque me gusta una buena biblioteca (que es una fortaleza de .NET), y me gustan los lenguajes estáticamente escritos. Boo es una buena alternativa. Pero realmente Haskell , OCaml , D , ML y demás están bien.
fuente