Preguntas frecuentes de Bjarne Stroustrup

Original source: https://www.stroustrup.com/bs_faq.html

Modificado el 23 de julio de 2021.

Estas son preguntas que la gente me hace a menudo. Si tiene mejores preguntas o comentarios sobre las respuestas, no dude en enviarme un correo electrónico. Recuerde que no puedo dedicar todo mi tiempo a mejorar mis páginas de inicio.

Esta página se concentra en opiniones personales y cuestiones generales relacionadas con la filosofía. Para preguntas que se relacionan más directamente con las características del lenguaje C++ y el uso de C++, consulte las preguntas frecuentes de la Fundación C++ o mis preguntas frecuentes sobre técnicas y estilos de C++ . Para conocer la terminología y los conceptos de C++, consulte mi glosario de C++ . Para obtener enlaces a fuentes útiles de información sobre C++, consulte mi página de C++ y mis preguntas frecuentes sobre C++11 . Para obtener información sobre mis libros (incluidas reseñas e información de soporte), consulte mi lista de libros . Para artículos y ISBN de traducciones de mis libros, consulte mi lista de publicaciones .

Table of Contents

¿Cómo se pronuncia “Bjarne Stroustrup”?

Puede resultar difícil para los no escandinavos. La mejor sugerencia que he escuchado hasta ahora fue “empieza diciéndolo varias veces en noruego, luego métete una papa en la garganta y hazlo de nuevo :-)”. Aquí hay un archivo wav .

Para las personas que no pueden recibir el sonido, aquí hay una sugerencia: Mis dos nombres se pronuncian con dos sílabas: Bjar-ne Strou-strup. Ni la B ni la J en mi nombre están acentuadas y el NE es bastante débil, por lo que tal vez Be-ar-neh o By-ar-ne me darían una idea. La primera U de mi segundo nombre realmente debería haber sido una V que hiciera que la primera sílaba terminara en la garganta: Strov-strup. La segunda U es un poco como la OO en OOP, pero aún corta; Quizás Strov-stroop dé una idea.

Sí, esta es probablemente la pregunta más frecuente 🙂

PD: Mi nombre es Bjarne, no Bjorn (no es un nombre), Bjørn (un nombre relacionado pero diferente), ni Barney (un nombre no relacionado). Mi segundo nombre es Stroustrup, no Stroustroup, Stroustrop, Strustrup, Strustrop, Strustroup, Straustrup ni Straustroup (los documentos que utilizan cada uno de estos errores ortográficos se pueden encontrar en Google).


¿Puedo hacerte una pregunta?

Ciertamente. Intento contestar mi correo electrónico. Sin embargo, trate de evitar hacer una pregunta que se responda en mis páginas de inicio. Además, no confíe en una respuesta rápida. Recibo muchos correos electrónicos.

Aquí hay enlaces a


¿Por qué no contestas tu correo electrónico?

Lo hago, pero recibo muchos correos electrónicos. Calculo que respondo a más del 95% de los mensajes (no spam) que recibo. Sin embargo, a veces me siento abrumado. Algunos mensajes se pierden en mi buzón, algunos se retrasan hasta que pueda encontrar tiempo, otros se retrasan hasta que consigo responder un conjunto de mensajes relacionados (esto sucede a menudo con los comentarios sobre posibles errores en mis libros). Desafortunadamente, los mensajes más largos y reflexivos tienen más probabilidades de retrasarse que los simples que tienen respuestas simples.

Además, si me envía un correo electrónico, intente asegurarse de que pueda responderle. Realmente odio cuando escribo y envié una respuesta, solo para descubrir que la dirección del remitente no es válida o es inaccesible.

Dos tipos de mensajes tienen una probabilidad relativamente alta de perderse: preguntas de tarea y preguntas del tipo “¿cómo uso esta biblioteca propietaria?”. Me entristece un poco no responder a las últimas preguntas porque a menudo la persona que pregunta no entiende que DOS, Windows o cualquier interfaz de C++ no es parte del estándar C++ (y no puedo seguir el ritmo de la gran cantidad de bibliotecas C++ ). Si no recibe una respuesta, considere si su pregunta fue de uno de estos tipos.

Además, a menos que proporciones tu nombre, es probable que borre el mensaje sin leer. Esta es una nueva política. Nunca fui un gran admirador de los seudónimos, pero encuentro que las posibilidades de tener una conversación técnica cortés con el tipo de persona que piensa que es genial esconderse detrás de un nombre como suuupergeeek o coolGuy3 es demasiado baja como para molestarme en intentarlo.


¿Por qué no haces que tu sitio web luzca moderno?

Soy un “proveedor de contenidos”, no un diseñador de sitios web. Puedo usar mi tiempo para mejorar el contenido o la apariencia, pero no ambos.

Lo que a alguien le parece “cool y moderno” a menudo es considerado de mal gusto por otra persona, y las modas cambian rápidamente. Además, el HTML muy simple se descarga y muestra más rápido que cualquier otra cosa, y muchas personas todavía sufren de conexiones web lentas.


¿Es “bjarne” un impostor?

Probablemente no. La mayoría de las publicaciones en grupos de noticias, entrevistas, etc. que dicen provenir de mí, en realidad provienen de mí. La excepción obvia es la infame “entrevista” del IEEE , que ya tiene más de 20 años y me parece bastante poco divertida. En caso de duda, considere el estilo y el contenido del mensaje sospechoso, busque otras publicaciones en el foro o pregunte.


¿Qué tienen de bueno las clases?

Las clases están ahí para ayudarle a organizar su código y razonar sobre sus programas. De manera más o menos equivalente, se podría decir que las clases están ahí para ayudarlo a evitar cometer errores y para ayudarlo a encontrar errores después de cometer un error. De esta forma, las clases ayudan significativamente al mantenimiento.

Una clase es la representación de una idea, un concepto, en el código. Un objeto de una clase representa un ejemplo particular de la idea en el código. Sin clases, un lector del código tendría que adivinar las relaciones entre elementos de datos y funciones; las clases hacen que dichas relaciones sean explícitas y “comprendidas” por los compiladores. Con las clases, una mayor parte de la estructura de alto nivel de su programa se refleja en el código, no sólo en los comentarios.

Una clase bien diseñada presenta una interfaz limpia y sencilla a sus usuarios, ocultando su representación y evitando que los usuarios tengan que conocer esa representación. Si la representación no debe estar oculta (por ejemplo, porque los usuarios deberían poder cambiar cualquier miembro de datos como quieran), puede pensar en esa clase como “simplemente una estructura de datos antigua y simple”; Por ejemplo:

Tenga en cuenta que incluso las estructuras de datos pueden beneficiarse de funciones auxiliares, como los constructores.

Al diseñar una clase, suele ser útil considerar qué es cierto para cada objeto de la clase y en todo momento. Esta propiedad se llama invariante. Por ejemplo, la invariante de un vector podría ser que su representación consista en un puntero a una cantidad de elementos y esa cantidad de elementos se almacene en un número entero. Es trabajo de cada constructor establecer la invariante de clase, de modo que cada función miembro pueda confiar en ella. Cada función miembro debe dejar el invariante válido al salir. Este tipo de pensamiento es particularmente útil para clases que administran recursos, como bloqueos, sockets y archivos. Por ejemplo, una clase de identificador de archivo tendrá la invariante de que contiene un puntero a un archivo abierto. El constructor del identificador de archivo abre el archivo. Los destructores liberan recursos adquiridos por los constructores. Por ejemplo, el destructor de un identificador de archivo cierra el archivo abierto por el constructor:

Si no ha programado con clases, encontrará partes de esta explicación oscuras y subestimará la utilidad de las clases. Busque ejemplos. Como todos los buenos libros de texto, TC++PL tiene muchos ejemplos. Para obtener un libro menos detallado y más fácil de abordar, consulte Un recorrido por C++ . La mayoría de las bibliotecas C++ modernas constan (entre otras cosas) de clases y un tutorial de biblioteca es uno de los mejores lugares para buscar ejemplos de clases útiles.


¿Qué es “OOP” y qué tiene de bueno?

Existen muchas definiciones de “orientada a objetos”, “programación orientada a objetos” y “lenguajes de programación orientados a objetos”. Para obtener una explicación más extensa de lo que considero “orientado a objetos”, lea Por qué C++ no es solo un lenguaje de programación orientado a objetos . Dicho esto, la programación orientada a objetos es un estilo de programación que se originó con Simula (¡hace más de 40 años!) y se basa en la encapsulación, la herencia y el polimorfismo. En el contexto de C++ (y muchos otros lenguajes con raíces en Simula), significa programar usando jerarquías de clases y funciones virtuales para permitir la manipulación de objetos de una variedad de tipos a través de interfaces bien definidas y para permitir que un programa se extienda incrementalmente. mediante derivación.

Ver ¿Qué tienen de bueno las clases? para tener una idea de lo bueno de las “clases sencillas”. El objetivo de organizar clases en una jerarquía de clases es expresar relaciones jerárquicas entre clases y utilizar esas relaciones para simplificar el código.

Para comprender realmente la programación orientada a objetos, busque algunos ejemplos. Por ejemplo, es posible que tenga dos (o más) controladores de dispositivo con una interfaz común:

Este controlador es simplemente una interfaz. Se define sin miembros de datos y con un conjunto de funciones virtuales puras. Se puede utilizar un controlador a través de esta interfaz y muchos tipos diferentes de controladores pueden implementar esta interfaz:

Tenga en cuenta que estos controladores contienen datos (estado) y se pueden crear objetos a partir de ellos. Implementan las funciones definidas en Driver. Podemos imaginar un controlador utilizado así:

El punto clave aquí es que f() no necesita saber qué tipo de controlador utiliza; todo lo que necesita saber es que se le ha pasado un conductor; es decir, una interfaz para muchos tipos diferentes de controladores. Podríamos invocar f() así:

Tenga en cuenta que cuando f() utiliza un controlador, el tipo correcto de operaciones se elige implícitamente en tiempo de ejecución. Por ejemplo, cuando a f() se le pasa d1, d.read() usa Driver1::read(), mientras que cuando a f() se le pasa d2, d.read() usa Driver2::read(). A esto a veces se le llama envío en tiempo de ejecución o envío dinámico. En este caso, no hay forma de que f() pueda saber con qué tipo de dispositivo se llama porque lo elegimos en función de una entrada.

Tenga en cuenta que la programación orientada a objetos no es una panacea. “POO” no significa simplemente “bueno”: si no existen relaciones jerárquicas inherentes entre los conceptos fundamentales de su problema, ninguna jerarquía y funciones virtuales mejorarán su código. La fortaleza de la POO es que hay muchos problemas que pueden expresarse de manera útil utilizando jerarquías de clases; la principal debilidad de la POO es que demasiadas personas intentan forzar demasiados problemas dentro de un molde jerárquico. No todos los programas deberían estar orientados a objetos. Como alternativas, considere clases simples , programación genérica y funciones independientes (como en matemáticas, C y Fortran).


¿Qué es la “programación genérica” ​​y qué tiene de bueno?

La programación genérica es una programación basada en la parametrización: Puedes parametrizar un tipo con otro (como un vector con sus tipos de elementos) y un algoritmo con otro (como una función de clasificación con una función de comparación). El objetivo de la programación genérica es generalizar un algoritmo o estructura de datos útil a su forma más general y útil. Por ejemplo, un vector de números enteros está bien y también lo es una función que encuentra el valor más grande en un vector de números enteros. Sin embargo, una solución genérica que proporcione un vector de cualquier tipo que el usuario quiera usar y una función que encuentre el valor más grande en cualquier vector es aún mejor:

Estos ejemplos son de STL (los contenedores y algoritmos forman parte de la biblioteca estándar ISO C++); para obtener una breve introducción, consulte Un recorrido por C++ de TC++PL .

En C++ 20 podemos simplificar ese ejemplo para:

La programación genérica es, en cierto modo, más flexible que la programación orientada a objetos. En particular, no depende de jerarquías. Por ejemplo, no existe una relación jerárquica entre un int y una cadena. La programación genérica generalmente está más estructurada que la programación orientada a objetos; de hecho, un término común utilizado para describir la programación genérica es “polimorfismo paramétrico”, siendo “polimorfismo ad hoc” el término correspondiente para la programación orientada a objetos. En el contexto de C++, la programación genérica resuelve todos los nombres en tiempo de compilación; no implica despacho dinámico (en tiempo de ejecución). Esto ha llevado a que la programación genérica se vuelva dominante en áreas donde el rendimiento en tiempo de ejecución es importante.

Tenga en cuenta que la programación genérica no es una panacea. Hay muchas partes de un programa que no necesitan parametrización y muchos ejemplos en los que se necesita el envío en tiempo de ejecución (OOP).


¿Por qué C++ permite código inseguro?

Es decir, ¿por qué C++ admite operaciones que pueden usarse para violar las reglas de seguridad de tipos estáticos (en tiempo de compilación)?

  • acceder al hardware directamente (por ejemplo, tratar un número entero como un puntero a (la dirección de) un registro de dispositivo)
  • para lograr un rendimiento óptimo en tiempo de ejecución y espacio (por ejemplo, acceso sin control a elementos de una matriz y acceso sin control a un objeto a través de un puntero)
  • ser compatible con C

Dicho esto, es una buena idea evitar el código inseguro como la plaga siempre que no necesites una de esas tres características:

  • no uses yesos
  • mantenga las matrices fuera de las interfaces (escóndelas en el interior de funciones y clases de alto rendimiento donde sean necesarias y escriba el resto del programa utilizando cadenas, vectores, etc. adecuados)
  • evite void* (manténgalos dentro de funciones y estructuras de datos de bajo nivel si realmente los necesita y presente interfaces seguras de tipo, generalmente plantillas, a sus usuarios)
  • evitar sindicatos
  • Si tiene dudas sobre la validez de un puntero, utilice un puntero inteligente en su lugar.
  • no utilice noticias ni eliminaciones “desnudas” (use contenedores, identificadores de recursos, etc., en su lugar)
  • no utilice funciones variadas de estilo … (“estilo printf”)
  • Evite macros excepto incluir guardias

Casi todo el código C++ puede seguir estas sencillas reglas. No se deje confundir por el hecho de que no puede seguir estas reglas si escribe código C o código estilo C en C++.

Para conocer un proyecto ambicioso para hacer que C++ sea más fácil de usar y más seguro sin dañar su eficiencia o flexibilidad, consulte las Directrices básicas de C++ .


¿Cuál es el mejor libro para aprender C++?

No existe un libro que sea mejor para todas las personas. No podría haber uno. Las personas son demasiado diferentes en la forma en que aprenden, en lo que ya saben, en lo que necesitan, en lo que quieren y en el tipo de esfuerzo que están dispuestas a hacer. Hay bastantes libros excelentes sobre C++.

Para las personas que no han programado antes o que vienen de otro lenguaje y desean una introducción relativamente sencilla al C++ moderno, considere Programación: principios y práctica con C++ . Este es el libro que escribí para una clase de programación de primer año (estudiantes universitarios de primer año) y se ha beneficiado de tres años de uso en el aula.

Para las personas que son programadores y están dispuestas a aprender nuevos conceptos y técnicas de un libro de texto clásico, recomiendo El lenguaje de programación C++ (4.ª edición) . El libro está dirigido a programadores con cierta experiencia y que deseen dominar C++. No está dirigido a personas que no son programadores y que intentan aprender su primer lenguaje de programación ni a programadores ocasionales que intentan obtener una comprensión superficial de C++ lo más rápido posible. En consecuencia, este libro se centra en conceptos y técnicas y se esfuerza por ser completo y preciso. Describe “C++ puro”, es decir, el lenguaje independientemente de cualquier entorno de desarrollo de software o biblioteca básica en particular (excepto la biblioteca estándar, por supuesto). Contiene una cobertura completa de la biblioteca estándar.

Si ya es un programador experimentado y desea una descripción general rápida de lo que C++ tiene para ofrecer, considere Un recorrido por C++ (segunda edición) . Presenta las características principales de C++ y su biblioteca estándar en 200 páginas.

Si desea saber por qué C++ es como es, eche un vistazo a El diseño y evolución de C++ (D&E). Comprender los criterios y restricciones de diseño ayuda a redactar mejores programas. Prosperar en un mundo abarrotado y cambiante: C++ 2006-2020 puede verse como una continuación actualizada de D&E.


¿Cuánto tiempo lleva aprender C++?

Eso depende de lo que quieras decir con “aprendizaje”. Si es programador de C, puede aprender suficiente C++ para ser más eficaz en la programación estilo C en un día.

En TAMU , utilizamos Programación: principios y práctica usando C++ para que los estudiantes de primer año (estudiantes de primer año) aprendan los fundamentos de C++ y las técnicas de programación que admite (en particular, programación orientada a objetos y programación genérica ) en un semestre.

Por otro lado, si desea sentirse completamente cómodo con todas las construcciones principales del lenguaje C++, con la abstracción de datos, la programación orientada a objetos, la programación genérica, el diseño orientado a objetos, etc., puede fácilmente dedicar uno o dos años, si aún no está familiarizado con esas técnicas (por ejemplo, de Java o C#).

¿Es ese entonces el tiempo que lleva aprender C++? Tal vez, pero claro, esa es la escala de tiempo que debemos considerar para convertirnos en mejores diseñadores y programadores. Si nuestro objetivo no es un cambio dramático en la forma en que trabajamos y pensamos sobre la construcción de sistemas, entonces ¿por qué molestarse en aprender un nuevo idioma? En comparación con el tiempo necesario para aprender a tocar bien el piano o dominar un idioma extranjero (natural), aprender un lenguaje y estilo de programación nuevos y diferentes es fácil.

Para obtener más observaciones sobre el aprendizaje de C++, consulte D&E o una nota de comp.lang.c++ que escribí hace algún tiempo.


Saber C es un requisito previo para aprender C++, ¿verdad?

Equivocado. El subconjunto común de C y C++ es más fácil de aprender que C. Habrá menos errores tipográficos que detectar manualmente (el sistema de tipos C++ es más estricto y expresivo), menos trucos que aprender (C++ le permite expresar más cosas sin circunloquios) y mejores bibliotecas disponibles. El mejor subconjunto inicial de C++ para aprender no es “todo C”.

Consulte Aprendizaje de C++ estándar como nuevo lenguaje para obtener una discusión sobre la elección de construcciones, técnicas y bibliotecas de C++ para el aprendizaje temprano. Para ver un ejemplo de libros que adoptan ese enfoque sistemáticamente, consulte Stroustrup: Programación: principios y práctica usando C++ y Koenig&Moo: “Accelerated C++” de la serie C++ In Depth de Addison Wesley .


¿Debería aprender un lenguaje OO puro antes que C++ para convertirme en un verdadero programador OO?

No. Aprender algo nuevo casi siempre es una buena idea. Sin embargo, cada idioma es diferente y tiene sus propios estilos y peculiaridades. El código escrito en algún estilo OO supuestamente “puro” modelado en algún otro lenguaje (peculiaridades y todo) a menudo es subóptimo y frustrante cuando se transcribe demasiado literalmente a C++. Además, “escribir simplemente código orientado a objetos” no es uno de mis ideales; vea mi discurso de apertura de OOPSLA Por qué C++ no es solo un lenguaje de programación orientado a objetos . Si quieres convertirte en un buen programador de C++ y no tienes algunos meses libres, concéntrate en C++ y los conceptos que encarna.


¿Cómo empiezo a aprender C++?

Naturalmente, eso depende en gran medida de lo que ya sabes y de tus razones para aprender C++. Si es un principiante en programación, le recomiendo encarecidamente que busque un programador experimentado que le ayude. De lo contrario, los errores inevitables sobre los conceptos del lenguaje y los problemas prácticos con la implementación que utilice pueden convertirse en serias frustraciones.

Necesitará un libro de texto para aprender C++. Este es el caso incluso cuando su implementación viene con una amplia documentación en línea. La razón es que el lenguaje y la documentación de la biblioteca junto con el código de muestra no son buenos profesores de conceptos. Normalmente, estas fuentes guardan silencio sobre por qué las cosas son como son y qué beneficios se pueden esperar (y cuáles no se deben esperar) de una técnica. Céntrese en conceptos y técnicas en lugar de detalles técnicos del lenguaje.

Al elegir un libro, busque uno que presente C++ estándar y utilice las funciones de la biblioteca estándar de forma integrada desde el principio. Por ejemplo, leer una cadena desde la entrada debería verse así

y no así

Busque recomendaciones de libros de programadores con sólida experiencia en C++.

Recomiendo Programación: principios y práctica con C++ , pero recuerde que ningún libro es el mejor para todos. Eche un vistazo a las reseñas de libros en el sitio ACCU (Asociación de Usuarios de C y C++).

Intente escribir C++ idiomático: evite simplemente escribir código en el estilo de su lenguaje anterior usando la sintaxis de C++; hay poco que ganar simplemente cambiando la sintaxis.


¿Me ayudarás con mi tarea?

No lo siento. No hago los deberes (de otras personas). Recibo demasiadas solicitudes de ayuda con la tarea y ayuda para encontrar errores en los programas de los estudiantes para poder encontrar tiempo. De todos modos, hacer que un experto distante arregle sus programas no es la mejor manera de aprender. Intente encontrar una persona local con experiencia en C++ a quien pueda pedirle orientación. Un buen mentor es la mejor ayuda que puede tener un estudiante; tal vez por eso no son fáciles de encontrar.

Además, no, no sugeriré “un buen proyecto en el que pueda trabajar un estudiante”. Mi experiencia es que aprender lo suficiente sobre un estudiante y su curso para saber qué nivel de dificultad se requiere y qué tipo de proyecto es de interés lleva tiempo. Pensar en un buen proyecto no es entonces trivial, y explicar exactamente qué es el proyecto y cómo abordarlo puede llevar varios mensajes y varias horas. Simplemente no tengo ese tipo de tiempo. Recuerde, estas solicitudes llegan al menos semanalmente. Finalmente, algunos estudiantes parecen tener la idea de que si sugiero un proyecto, estoy moralmente obligado a brindar ayuda bastante detallada para completarlo.

Ideas: mira los ejercicios en TC++PL u otros buenos libros de texto. Muchos de esos ejercicios están diseñados para mantener ocupado al estudiante durante varios días, y leer esos ejercicios puede inspirar a un estudiante emprendedor a hacer algo similar. O mire la parte de su mundo que no está relacionada con la informática: tal vez un proyecto de biología podría necesitar soporte para un nuevo dispositivo de medición o un amigo que estudia historia podría usar una interfaz de base de datos mejorada. Muchos de los mejores proyectos y los mejores usos de las computadoras se encuentran fuera de la informática tradicional.

Consulte también mis preguntas frecuentes sobre técnicas y estilos de C++ . Los verdaderos principiantes que se enfrentan a su primer ejercicio de “leer algunos datos, hacer algo con ellos y producir algún resultado” podrían estar interesados ​​en un programa muy simple o un programa que lea una cadena de entrada .


¿Dónde puedo conseguir un compilador de C++ gratuito?

De muchos lugares; consulte mi lista de compiladores de C++.


¿Eres sueco?

No, soy danés. Échale un vistazo a mi biografía.


¿Cuál es la mejor manera de mejorar mis programas C++?

No podría decirlo. Eso depende de cómo lo uses. La mayoría de la gente subestima las clases y plantillas abstractas. Por el contrario, la mayoría de la gente abusa seriamente de las conversiones y macros. Eche un vistazo a uno de mis artículos libros para obtener ideas. Una forma de pensar en las clases y plantillas abstractas es como interfaces que permiten una presentación de servicios más limpia y lógica que la que es fácil de proporcionar a través de funciones o jerarquías de clases de raíz única. Consulte mis Preguntas frecuentes sobre estilos y técnicas para ver algunos ejemplos e ideas específicos.


¿Importa qué lenguaje de programación uso?

Sí, pero no esperes milagros. Algunas personas parecen creer que un lenguaje de programación puede o al menos debería resolver la mayoría de sus problemas de construcción de sistemas. Están condenados a buscar eternamente el lenguaje de programación perfecto y a decepcionarse repetidamente. Otros descartan los lenguajes de programación como “detalles de implementación” sin importancia y ponen su dinero en procesos de desarrollo y métodos de diseño. Están condenados a programar en COBOL, C y lenguajes de diseño propietarios para siempre. Un buen lenguaje, como C++, puede hacer mucho por un diseñador y un programador, siempre que se entiendan y respeten claramente sus fortalezas y limitaciones.


¿El comité de estándares ANSI/ISO echó a perder C++?

No. Ellos/nosotros hicimos un buen trabajo. Puedes objetar los detalles (y lo hago, a veces en voz alta), pero estoy contento con el lenguaje y la nueva biblioteca estándar. ISO C++ es un lenguaje mejor y más coherente que las versiones anteriores de C++. Hoy en día se pueden escribir programas C++ mucho más elegantes y fáciles de mantener de lo que era posible cuando comenzó el proceso de estándares. La nueva biblioteca estándar también es una verdadera bendición. La provisión de cadenas, listas, vectores, mapas y algoritmos básicos para tipos tan fundamentales marca una gran diferencia en la forma en que uno puede abordar C++. Consulte los capítulos de la biblioteca de El lenguaje de programación C++ o Un recorrido por C++ o uno de mis artículos recientes.


¿Cuándo tendremos un estándar C++?

Tenemos uno desde 1998. El segundo estándar llegó en 2011.

El estándar actual, C++14 , se aprobó en 2014 y ya se están comercializando buenas implementaciones . C++11/C++14 se describe en las ediciones actuales de mis libros .


¿Dónde puedo obtener una versión del estándar legible por máquina?

El estándar C++ (ISO/IEC 14882) está disponible para descargar en ANSI Electronic Store . Busque “14882” y encontrará “Lenguajes de programación INCITS/ISO/IEC 14882-2003 – C++”. El costo es (mientras escribo esto) US$30,00 pagaderos en línea mediante tarjeta de crédito. El documento descargado está en formato PDF, con un tamaño total de aproximadamente 3 Mb.

Consulte ISOcpp/estandarización para obtener información sobre el estándar, el esfuerzo de estandarización y un documento de trabajo tardío (disponible de forma gratuita). El estándar actual es C++17, pero C++20 ha sido aprobado y será oficial a finales de 2020.

Tenga en cuenta que el estándar no es un tutorial; Incluso los programadores expertos obtendrán mejores resultados si aprenden sobre C++ y las nuevas funciones de C++ en un libro de texto.


¿Hay alguna característica que le gustaría eliminar de C++?

No precisamente. Las personas que hacen este tipo de preguntas suelen pensar en una de las características principales, como la herencia múltiple, las excepciones, las plantillas o la identificación de tipos en tiempo de ejecución. C++ estaría incompleto sin ellos. He revisado su diseño a lo largo de los años y, junto con el comité de estándares, he mejorado algunos de sus detalles, pero ninguno se pudo eliminar sin causar daños.

La mayoría de las características que no me gustan desde la perspectiva del diseño del lenguaje (por ejemplo, la sintaxis del declarador y la decadencia de la matriz) son parte del subconjunto C de C++ y no se pueden eliminar sin dañar a los programadores que trabajan en condiciones del mundo real. La compatibilidad de C++ con C fue una decisión clave de diseño del lenguaje más que un truco de marketing. La compatibilidad ha sido difícil de lograr y mantener, pero se obtuvieron beneficios reales para los programadores reales, y aún se obtienen hoy en día. Actualmente, C++ tiene características que permiten al programador abstenerse de utilizar las características más problemáticas de C. Por ejemplo, se pueden utilizar contenedores de biblioteca estándar como vector, lista, mapa y cadena para evitar la manipulación de punteros de bajo nivel más complicada.


¿Cuál es la diferencia entre C++ 98, C++ 11 y C++ 14?

Y C++17 y C++20. Eso no es algo que se pueda resumir fácilmente. Para la mayoría de los propósitos prácticos, C++20 es compatible con versiones anteriores de C++11, es decir, es casi completamente compatible con C++98. Hay una sección de compatibilidad en la parte posterior del estándar que detalla los problemas de compatibilidad.


¿Cómo será el próximo estándar?

Ese será C++17. Es un poco pronto para decir con seguridad qué ofrecerá C++17, pero se pretende que sea una actualización importante y presenté algunas de mis ideas en una reunión de estándares de 2015 . Tenga en cuenta que es poco probable que obtenga todo lo que deseo. Para obtener una lista completa de propuestas, consulte el sitio del WG21 .


¿Cuándo publicarán la cuarta edición de “El lenguaje de programación C++”?

Está impreso: El lenguaje de programación C++ (4.ª edición) . Addison-Wesley. ISBN 978-0321563842. Mayo 2013.

Ahora se envía desde Amazon, desde el editor y desde otros lugares.

No hay planes actuales para una quinta edición.


¿Cuál es la diferencia entre los libros “TC++PL” y “Programación”?

El lenguaje de programación C++ está escrito principalmente para programadores experimentados que quieran aprender C++. Su estilo es el de un libro profesional. Programación: principios y práctica con C++ está escrito principalmente para personas que desean aprender a programar con C++. Puede ser utilizado/leído por personas sin experiencia en programación o con poca experiencia en programación, así como por personas que quieran aprender técnicas de programación modernas, como la programación orientada a objetos y la programación genérica, compatible con C++. Su estilo es el de un libro de texto.

Un resumen:

  • TC++PL4 : Para programadores que quieran conocer en profundidad el C++ moderno (C++11)
  • Tour++ : para programadores que desean una descripción general del C++ moderno (C++17 más un poco de C++20)
  • PPP : Para principiantes y programadores con conocimientos débiles de C++ (C++14)
  • D&E : Para personas interesadas en los principios y la historia del diseño.
  • Otros: No los leas; estan desactualizados

¿Te gustan los libros electrónicos?

Me gustan los libros electrónicos sobre historias de crímenes y ciencia ficción. No creo que estén preparados para recibir información técnica seria. Para eso prefiero el papel, aunque tenga que esperar un par de días y cargar algo de peso extra. Un buen libro de texto, abierto sobre una mesa, mostrará dos páginas, un área aproximadamente tres veces mayor que la de un lector de libros electrónicos. Leer en una pantalla grande y de buena calidad está bien, simplemente está bien.


¿Dónde encuentro copias gratuitas de sus libros legibles por máquina?

No existen copias legales gratuitas de mis libros legibles por máquina. Si ve una copia disponible gratuitamente, debe ser una violación de derechos de autor (es decir, fue robada).

Addison-Wesley ofrece versiones electrónicas a través del servicio de libros en línea Safari y en otros lugares.


¿Qué compilador de C++ recomiendas? ¿Qué bibliotecas?

No lo recomiendo. No sería justo. Sin embargo, obtenga una versión reciente. Naturalmente, los compiladores más nuevos se aproximan mucho más al estándar ISO que los compiladores de hace unos años.

Para obtener una lista incompleta de implementaciones de C++, consulte mi lista de compiladores de C++.

Además, cuando sea posible, prefiera la biblioteca estándar a las “bibliotecas básicas” no estándar y trate de minimizar el uso de extensiones propietarias.


¿Son malas las listas?

Según algunos rincones de la Web, tengo la impresión de que los vectores siempre son mejores que las listas enlazadas y que no conozco otras estructuras de datos, como árboles (por ejemplo, std::set ) y tablas hash (por ejemplo, std ::mapa_desordenado ). Obviamente, eso es absurdo.

El problema parece ser un pequeño ejercicio interesante que John Bentley me propuso una vez: Insertar una secuencia de números enteros aleatorios en una secuencia ordenada, luego eliminar esos elementos uno por uno según lo determinado por una secuencia aleatoria de posiciones: ¿Utiliza un vector ( una secuencia de elementos asignados de forma contigua) o una lista enlazada? Por ejemplo, consulte Desarrollo de software para infraestructura . Utilizo este ejemplo para ilustrar algunos puntos, fomentar la reflexión sobre algoritmos, estructuras de datos y arquitectura de máquinas, y concluyo:

  • no almacene datos innecesariamente,
  • mantener los datos compactos y
  • acceder a la memoria de forma predecible.

Note la ausencia de “lista” y “vector” en la conclusión. No confunda un ejemplo con lo que el ejemplo pretende ilustrar.

Utilicé ese ejemplo en varias charlas, en particular:

Este vídeo ha sido popular: se ha descargado más de 250.000 veces (más otras más de 50.000 veces en varios otros sitios). Mi impresión es que muchos espectadores no entendieron que el propósito de ese ejemplo es ilustrar algunos principios generales y hacer pensar a la gente. Inicialmente, la mayoría de la gente dice “¡Lista, por supuesto!” (He intentado hacer esa pregunta muchas veces) debido a las muchas inserciones y eliminaciones “en el medio” (las listas son buenas para eso). Esa respuesta es total y dramáticamente errónea, por lo que es bueno saber por qué.

He estado usando el ejemplo durante años e hice que estudiantes de posgrado implementaran y midieran docenas de variantes de este ejercicio y diferentes ejercicios. Se pueden encontrar ejemplos y mediciones de otros en la Web. Por supuesto,

  • He probado mapas (son mucho mejores que las listas, pero aún más lentos que los vectores)
  • He probado tamaños de elementos mucho más grandes (con el tiempo, las listas cobran vida)
  • He usado búsqueda binaria e inserción directa de vectores (sí, se aceleran aún más)
  • Verifiqué mi teoría (no, no estoy violando ninguna regla de complejidad de O grande; es solo que algunas operaciones pueden ser dramáticamente más costosas para una estructura de datos en comparación con otra)
  • Tengo enlaces preasignados (eso es mejor que std::list pero el recorrido aún reduce el rendimiento)
  • He usado listas enlazadas individualmente, forward_list s, (eso no hace mucha diferencia, pero hace que sea un poco más difícil garantizar que el código de usuario sea 100% equivalente)
  • Sé (y digo) que las listas de 500K no son comunes (pero eso no importa para mi punto principal). Usamos muchas estructuras (grandes y pequeñas) donde se puede elegir entre representación vinculada y contigua.
  • Sé que para la inserción push_front() es más rápido para std::list sy push_back() s es más rápido para vector s. Puedes construir ejemplos para ilustrar eso, pero este ejemplo no es uno de esos.

Mi punto no se refiere a las listas como tales. Tienen sus usos, pero este ejemplo no es uno de ellos. No confunda el ejemplo con lo que se utiliza para ilustrar. Este ejemplo trata sobre el uso de la memoria: muy a menudo creamos una estructura de datos, hacemos algunos cálculos que requieren acceso (a menudo, recorrido) y luego la eliminamos. La secuencia ordenada es simplemente un ejemplo de dicho uso y el ejemplo se presenta para que la gente piense en lo que importa en tales casos. Mi sugerencia es:

  • no almacene datos innecesariamente,
  • mantener los datos compactos y
  • acceder a la memoria de forma predecible.

Hago hincapié en la importancia de los efectos de caché. En mi experiencia, todos los expertos, excepto los verdaderos, tienden a olvidarlos cuando se habla de algoritmos.

Y sí, mi recomendación es usar std::vector de forma predeterminada. De manera más general, utilice una representación contigua a menos que exista una buena razón para no hacerlo. Al igual que C, C++ está diseñado para hacer eso de forma predeterminada.

Además, no haga declaraciones sobre el rendimiento sin mediciones. He visto un caso en el que cambiar una lista de cero a dos elementos a un vector de cero a dos elementos supuso una diferencia de factor de dos en un algoritmo. No esperaba eso. Tampoco lo hicieron otros expertos que examinaron el código.


¿Es Java el lenguaje que habrías diseñado si no tuvieras que ser compatible con C?

No. Java ni siquiera está cerca. Si la gente insiste en comparar C++ y Java, como parece hacer, les sugiero que lean El diseño y evolución de C++ (D&E) para ver por qué C++ es como es, y que consideren ambos lenguajes a la luz de los criterios de diseño que presento. configurado para C++. Esos criterios obviamente diferirán de los criterios del equipo Java de Sun. A pesar de las similitudes sintácticas, C++ y Java son lenguajes muy diferentes. En muchos sentidos, Java parece más cercano a Smalltalk que a C++.

Gran parte de la relativa simplicidad de Java es, como ocurre con la mayoría de los lenguajes nuevos, en parte una ilusión y en parte una función de su carácter incompleto. A medida que pase el tiempo, Java crecerá significativamente en tamaño y complejidad. Duplicará o triplicará su tamaño y aumentará las extensiones o bibliotecas dependientes de la implementación. Así se ha desarrollado todo lenguaje comercialmente exitoso. Basta con mirar cualquier idioma que considere exitoso a gran escala. No conozco excepciones y hay buenas razones para este fenómeno. [Escribí esto antes del 2000; ahora (2012), la parte del lenguaje de la especificación Java 7 es ligeramente más larga en términos de número de páginas que la especificación del lenguaje ISO C++11.]

He comentado (negativamente) sobre la exageración de Java y atribuí gran parte del éxito de Java al marketing. Por ejemplo, consulte mi artículo HOPL-3 . Hoy (2010), las afirmaciones que se hacen sobre Java se basan más en la realidad y son menos gratuitamente despectivas sobre las alternativas. Esto no siempre fue así. Por ejemplo, compare el documento técnico de Java original de 1995 con las versiones que encuentre en la web (a veces denominadas “el documento técnico de Java original”); La página 69 sería un buen lugar para comenzar.

Java no es independiente de la plataforma; es una plataforma. Al igual que Windows, es una plataforma comercial propietaria. Es decir, puede escribir programas para Windows/Intel o Java/JVM, y en cada caso está escribiendo código para una plataforma propiedad de una sola corporación y modificada para el beneficio comercial de esa corporación. Se ha señalado que puede escribir programas en cualquier idioma para la JVM y las instalaciones de los sistemas operativos asociados. Sin embargo, la JVM, etc., están muy predispuestas a favor de Java. No está ni cerca de ser un VM/OS general razonablemente neutral en cuanto al lenguaje.

Personalmente, me quedo con C++ razonablemente portátil para la mayor parte del tipo de trabajo en el que pienso más y uso una variedad de lenguajes para el resto.


¿Qué opinas de C#?

No tengo comentarios sobre C# como lenguaje. Hará falta mucho para convencerme de que el mundo necesita otro lenguaje propietario. Será especialmente difícil convencerme de que necesita un lenguaje que esté estrechamente integrado con un sistema operativo propietario específico.

Si desea escribir exclusivamente para la plataforma .Net, C# no es la peor alternativa, pero recuerde que C++ es una alternativa fuertemente respaldada, aunque menos promocionada, en esa plataforma.


¿Qué opinas de C++/CLI?

C++/CLI es un conjunto de extensiones de ISO C++ que proporciona una “vinculación” extremadamente completa de C++ a la CLI (Common Language Infrastructure) de Microsoft. Ha sido estandarizado por ECMA (ECMA-372). Estoy feliz de que haga que todas las funciones de la CLI sean fácilmente accesibles desde C++ y estoy feliz de que C++/CLI sea un lenguaje mucho mejor que su predecesor “Managed C++”. Sin embargo, estoy menos contento de que C++/CLI logre sus objetivos esencialmente aumentando C++ con una característica de lenguaje separada para cada característica de CLI (interfaces, propiedades, genéricos, punteros, herencia, enumeraciones y mucho, mucho más). Esto será una fuente importante de confusión (lo que sea que alguien haga o diga). La riqueza de nuevas funciones de lenguaje en C++/CLI en comparación con el estándar ISO C++ tienta a los programadores a escribir código no portátil que (a menudo de manera invisible) queda íntimamente ligado a Microsoft Windows.

La CLI proporciona un conjunto de interfaces (para las instalaciones del sistema) que son muy diferentes de las interfaces tradicionales para las instalaciones y aplicaciones del sistema operativo. En particular, estas interfaces tienen una semántica que no se puede expresar completa o convenientemente en lenguajes de programación convencionales. Una forma de describir CLI es como una “plataforma” (parcial) o “máquina virtual”. Consiste en un gran conjunto de características del lenguaje (herencia, métodos, construcciones de bucle, mecanismos de devolución de llamadas, etc.), que admiten un gran conjunto de bibliotecas básicas (BCL), además de un elaborado sistema de metadatos. La CLI a veces se describe como “idioma neutral”. Sin embargo, un lenguaje que no acepta un gran subconjunto de estas funciones no puede utilizar ni siquiera las funciones básicas de .Net (o futuras instalaciones de Microsoft Windows, suponiendo que los planes de Microsoft no cambien) y un lenguaje que no puede expresar todas estas características no puede ser Se utiliza para la implementación de recursos destinados a ser utilizables por otros idiomas. Por lo tanto, CLI es “neutral en cuanto al idioma” sólo en el sentido de que cada idioma debe admitir todas las características de CLI para ser “de primera clase” en .Net.

Prefiero que un enlace sea unas pocas primitivas, expresables como llamadas a funciones simples y estructuras de datos simples en cualquier idioma, posiblemente encapsuladas en bibliotecas específicas del idioma. En el caso de la CLI, esto, en el mejor de los casos, se puede hacer únicamente para los consumidores de las instalaciones de la CLI. Un lenguaje utilizado para producir módulos CLI debe poder expresar todas las funciones de CLI, incluidos los metadatos. Sólo un lenguaje que pueda hacer eso puede considerarse un lenguaje de programación de sistemas en .Net. Por lo tanto, el equipo de Microsoft C++ concluyó que sus clientes sólo aceptan las funciones de lenguaje integradas. Su diseño refleja una visión que no acepta absolutamente ninguna restricción sobre qué parte de CLI se puede expresar en C++ con las extensiones C++/CLI, absolutamente ninguna verbosidad en comparación con otros lenguajes cuando se utilizan las funciones de CLI y absolutamente sin gastos generales en comparación con otros lenguajes. Su objetivo es preservar C++ como el lenguaje de programación de sistemas dominante para Windows.

Como siempre, pongo un gran énfasis en la portabilidad y recomiendo a las personas que diseñen aplicaciones de modo que el acceso a las instalaciones específicas del sistema se realice a través de interfaces bien definidas especificadas en ISO C++ (por ejemplo, no usar C++/CLI directamente). En Windows, esto a veces será un inconveniente en comparación con el uso directo de las funciones C++/CLI, pero es la única manera de obtener portabilidad y cierto grado de independencia del proveedor. Obviamente, ese enfoque independiente de la CLI no se puede mantener si el propósito de un fragmento de código es proporcionar una interfaz CLI para ser consumida por otro código. Tenga en cuenta que reconozco la necesidad de extensiones específicas del sistema y que Microsoft no es el único proveedor de C++ con tales extensiones, simplemente prefiero tratar con dichas extensiones a través de una “interfaz delgada” especificada en el estándar ISO C++.

Cómo abordar las extensiones específicas del sistema es una cuestión intrínsecamente difícil. El equipo de Microsoft C++, especialmente Herb Sutter, ha mantenido un diálogo activo con (otros) miembros del comité de estándares ISO C++ para que eventualmente se resuelva la relación entre ISO C++ y su superconjunto C++/CLI. Tenemos un largo historial de trabajo conjunto constructivo en el comité ISO C++. Además, para minimizar la confusión entre ISO C++ y las extensiones C++/CLI, Microsoft ahora está revisando su documentación de Visual C++ para intentar distinguir claramente C++/CLI de ISO C++ (C++ simple y no calificado significa ISO C++). Espero que otros sigan ese ejemplo.

Sobre la difícil y controvertida cuestión de cómo se llamarán las extensiones/enlaces CLI a C++, prefiero C++/CLI como abreviatura de “Las extensiones CLI a ISO C++”. Mantener C++ como parte del nombre recuerda a las personas cuál es el lenguaje base y ayudará a mantener C++ como un subconjunto adecuado de C++ con las extensiones C++/CLI. Los problemas de compatibilidad de C/C++ demuestran lo importante que es mantener esa propiedad de subconjunto.

Aquí hay algunos documentos relacionados con C++/CLI:


¿Por qué estás tan interesado en la portabilidad?

El software exitoso tiene una larga vida; esperanzas de vida de décadas no son infrecuentes. Una buena aplicación/programa a menudo sobrevive al hardware para el que fue diseñado, al sistema operativo para el que fue escrito, al sistema de base de datos que utilizó inicialmente, etc. A menudo, un buen software sobrevive a las empresas que suministraron las tecnologías básicas utilizadas para construirlo. él.

A menudo, una aplicación/programa exitoso tiene clientes/usuarios que prefieren una variedad de plataformas. El conjunto de plataformas deseables cambia a medida que cambia la población de usuarios. Estar vinculado a una única plataforma o un único proveedor limita el uso potencial de la aplicación/programa.

Obviamente, la independencia total de la plataforma es incompatible con la capacidad de utilizar todas las funciones específicas de la plataforma. Sin embargo, a menudo se puede aproximar la independencia de la plataforma para una aplicación accediendo a las instalaciones de la plataforma a través de una “interfaz delgada” que representa la visión de la aplicación de su entorno como una biblioteca.


¿Realmente recomiendas Ada en lugar de C++ para proyectos más grandes?

No. No tengo idea de quién inició ese rumor, pero debe haber sido un devoto de Ada demasiado entusiasta o malicioso.


¿Compararías C++ con “algún lenguaje”?

No, lo siento, no lo haré. Puede encontrar el motivo en las notas introductorias de El diseño y evolución de C++ :

“Varios revisores me pidieron que comparara C++ con otros lenguajes. Decidí no hacerlo. De este modo, reafirmé una opinión firmemente mantenida desde hace mucho tiempo: las comparaciones de lenguajes rara vez son significativas y aún menos justas. Una buena comparación de los principales programas Los idiomas requieren más esfuerzo del que la mayoría de la gente está dispuesta a gastar, experiencia en una amplia gama de áreas de aplicación, un mantenimiento rígido de un punto de vista distante e imparcial y un sentido de justicia. No tengo tiempo y, como diseñador de C++, mi imparcialidad nunca sería completamente creíble.

También me preocupa un fenómeno que he observado repetidamente en intentos honestos de comparar idiomas. Los autores se esfuerzan por ser imparciales, pero están irremediablemente sesgados al centrarse en una sola aplicación, un solo estilo de programación o una sola cultura entre los programadores. Peor aún, cuando un idioma es significativamente más conocido que otros, se produce un cambio sutil de perspectiva: los fallos en el lenguaje conocido se consideran menores y se presentan soluciones simples, mientras que fallos similares en otros lenguajes se consideran fundamentales. A menudo, las soluciones alternativas comúnmente utilizadas en los idiomas menos conocidos son simplemente desconocidas para las personas que hacen la comparación o se consideran insatisfactorias porque no serían viables en el idioma más familiar.

De manera similar, la información sobre el idioma más conocido tiende a estar completamente actualizada, mientras que para el idioma menos conocido, los autores se basan en información de varios años de antigüedad. Para los lenguajes que valen la pena comparar, una comparación del lenguaje X tal como se definió hace tres años con el lenguaje Y tal como aparece en la última implementación experimental no es justa ni informativa. Por lo tanto, restrinjo mis comentarios sobre lenguajes distintos de C++ a generalidades y comentarios muy específicos”.

Dicho esto, considero que C++ es la mejor opción como lenguaje de programación para una amplia variedad de personas y aplicaciones.


Otros comparan sus lenguajes con C++; ¿Eso no te molesta?

Lo hace cuando se hace de manera incompetente o con fines de lucro comercial. Las comparaciones más difundidas tienden a ser aquellas escritas por defensores de algún lenguaje, Z, para demostrar que Z es mejor que otros lenguajes. Dado su amplio uso, C++ suele encabezar la lista de lenguajes que los defensores de Z quieren demostrar que son inferiores. A menudo, estos artículos son “publicados” o distribuidos por una empresa que vende Z como parte de una campaña de marketing. Sorprendentemente, muchos parecen tomarse en serio un artículo no revisado escrito por personas que trabajan para una empresa que vende Z “que demuestra” que Z es mejor. Un problema es que siempre hay algo de verdad en tales comparaciones. Después de todo, ningún idioma es mejor que otro en todos los sentidos posibles. Ciertamente, C++ no es perfecto, pero la verdad selectiva puede ser muy seductora y, en ocasiones, completamente engañosa.

Cuando analice una comparación de idiomas, considere quién la escribió, considere cuidadosamente si las descripciones son objetivas y justas, y también si los criterios de comparación son en sí mismos justos para todos los idiomas considerados. Esto no es facil.


¿No compararás C++ con otros lenguajes, pero escribes diatribas sobre C++?

No escribo diatribas (esa es una caracterización hostil de algún texto), pero sí considero razonable -posiblemente incluso un deber- que alguien que diseñó un lenguaje explique sus virtudes y lo defienda contra caracterizaciones hostiles. Ver mi lista de publicaciones . En particular, consulte mis artículos extensos y revisados ​​por pares para la Conferencia sobre Historia de la Programación de ACM:

A menudo, también señalo las limitaciones de C++ y los supuestos fundamentales del diseño de C++ (por ejemplo, ver D&E ).


C es mejor que C++ para proyectos pequeños, ¿verdad?

No en mi opinión. Nunca vi un proyecto en el que C fuera mejor que C++ por ningún motivo excepto por la falta de un buen compilador de C++.


¿Es C un subconjunto de C++?

En sentido matemático estricto, C no es un subconjunto de C++. Hay programas que son válidos en C pero no válidos en C++ e incluso algunas formas de escribir código que tienen un significado diferente en C y C++. Sin embargo, C++ admite todas las técnicas de programación admitidas por C. Cada programa C se puede escribir esencialmente de la misma manera en C++ con la misma eficiencia de tiempo de ejecución y espacio. No es raro poder convertir decenas de miles de líneas de ANSI C a C++ estilo C en unas pocas horas. Por lo tanto, C++ es tanto un superconjunto de ANSI C como ANSI C es un superconjunto de K&R C y tanto como ISO C++ es un superconjunto de C++ tal como existía en 1985.

C bien escrito tiende a ser C++ legal también. Por ejemplo, todos los ejemplos de Kernighan & Ritchie: “El lenguaje de programación C (segunda edición)” también son un programa C++.

Ejemplos de problemas de compatibilidad con C/C++:

Llamar a una función no declarada es un estilo pobre en C e ilegal en C++. También lo es pasar argumentos a una función usando una declaración que no enumera los tipos de argumentos:

En C, un void* se puede convertir implícitamente a cualquier tipo de puntero, y la asignación de almacenamiento gratuito generalmente se realiza usando malloc() que no tiene forma de verificar si se solicita “suficiente” memoria:

Tenga en cuenta el posible error de alineación causado por la conversión implícita de void* a int*. Consulte la alternativa de C++ a void* y malloc() .

Al convertir de C a C++, tenga en cuenta que C++ tiene más palabras clave que C: clase int = 2; /* ok en C. Error de sintaxis en C++ */ intvirtual = 3; /* ok en C. Error de sintaxis en C++ */ Excepto por algunos ejemplos como los que se muestran arriba (y que se enumeran en detalle en el estándar C++ y en el Apéndice B del lenguaje de programación C++ (tercera edición) ), C++ es un superconjunto de C. (El Apéndice B está disponible para descargar) .

Tenga en cuenta que “C” en los párrafos anteriores se refiere a Classic C y C89. C++ no es descendiente de C99; C++ y C99 son hermanos. C99 presenta varias oportunidades novedosas para las incompatibilidades de C/C++ .


¿Cuál es la diferencia entre C y C++?

C++ es un descendiente directo de C que conserva casi todo C como un subconjunto. C++ proporciona una verificación de tipos más sólida que C y admite directamente una gama más amplia de estilos de programación que C. C++ es “un mejor C” en el sentido de que admite los estilos de programación realizados utilizando C con una mejor verificación de tipos y más soporte de notación (sin pérdida). de eficiencia). En el mismo sentido, ANSI C es mejor C que K&R C. Además, C++ admite la abstracción de datos, la programación orientada a objetos y la programación genérica (consulte mis libros ).

Nunca he visto un programa que pueda expresarse mejor en C que en C++ (y no creo que tal programa pueda existir: cada construcción en C tiene un equivalente obvio en C++). Sin embargo, todavía existen algunos entornos donde el soporte para C++ es tan débil que existe una ventaja al usar C en su lugar. Sin embargo, no quedan muchos de ellos; consulte mi lista de compiladores (incompleta) .

Para una discusión sobre el diseño de C++, incluida una discusión sobre su relación con C, consulte El diseño y la evolución de C++ .

Tenga en cuenta que “C” en los párrafos anteriores se refiere a Classic C y C89. C++ no es descendiente de C99; C++ y C99 son hermanos. C99 presenta varias oportunidades novedosas para las incompatibilidades de C/C++ . Aquí hay una descripción de las diferencias entre C++98 y C99 .


¿De verdad crees que C y C++ podrían fusionarse en un solo lenguaje?

Creo que sería algo muy bueno para la comunidad C/C++ si así fuera. Es decir, si se eliminaran sistemática y completamente las incompatibilidades C/C++ y se organizara la evolución futura para evitar que surgieran nuevas incompatibilidades. Si eso es posible es otra cuestión.

Mi punto básico es que las incompatibilidades actuales de C/C++ son “accidentes de la historia” que no tienen razones fundamentales detrás (aunque todas “parecieron una buena idea en ese momento” para algunas personas competentes y bien intencionadas). Las incompatibilidades de C/C++ no proporcionan ningún beneficio a la comunidad en general, causan serios problemas a una gran parte de la comunidad de C/C++ y podrían, con gran dificultad, eliminarse.

Para una presentación mucho más detallada de mis puntos de vista sobre la compatibilidad con C/C++, consulte la serie de artículos que escribí sobre esto:

  • B. Stroustrup: C y C++: estudios de casos de compatibilidad . El diario de usuarios de C/C++. Septiembre de 2002.
  • B. Stroustrup: C y C++: un caso de compatibilidad . El diario de usuarios de C/C++. Agosto de 2002.
  • B. Stroustrup: C y C++: hermanos . El diario de usuarios de C/C++. Julio de 2002.
  • B. Stroustrup: Rivalidad entre hermanos: C y C++ . AT&T Labs – Informe técnico de investigación. TD-54MQZY. Enero de 2002.

Me imagino que si se eliminaran las incompatibilidades (haciendo cambios tanto en C como en C++), todavía habría entidades llamadas C y C++, pero entonces C realmente se definiría como un subconjunto de C++ .

Tenga en cuenta que estos artículos se escribieron a finales de 2001 y principios de 2002, cuando todavía era posible imaginar una acción coordinada por parte de los comités de estándares C y C++ que condujera a resultados prácticos para finales de la década. Esto no sucedió.


¿Por qué hiciste que C++ fuera (casi) compatible con C?

Quería que C++ fuera compatible con un lenguaje completo con suficiente rendimiento y flexibilidad incluso para la programación de sistemas más exigente. Tenía un pavor absoluto de producir otro lenguaje bonito con limitaciones involuntarias. Consulte la Sección 2.7 de El diseño y evolución de C++ para obtener detalles históricos y lea los artículos en ¿ Realmente crees…? para una discusión técnica (retrospectiva) sobre problemas de compatibilidad con C/C++.

En ese momento, consideraba que C era el mejor lenguaje de programación de sistemas disponible. Eso no era tan obvio entonces (1979) como lo fue más tarde, pero tenía expertos como Dennis Ritchie , Steve Johnson, Sandy Fraser , Greg Chesson, Doug McIlroy y Brian Kernighan al final del pasillo de quienes podía aprender y recibir comentarios. Sin su ayuda y consejo, y sin C, C++ habría nacido muerto.

Contrariamente a los repetidos rumores, nunca me dijeron que tenía que usar C; ni nunca me dijeron que no usara C. De hecho, el primer manual de C++ surgió de una fuente troff del manual de C que me dio Dennis. En los laboratorios Bell se diseñaron muchos lenguajes nuevos; Al menos en “Investigación”, no había reglas que hicieran cumplir la intolerancia lingüística.


¿Qué opinas de C/C++?

No, esa no es realmente una pregunta que recibo a menudo. En ese sentido, es la única “Pregunta frecuente falsa” en estas Preguntas frecuentes. Sin embargo, debería ser una pregunta frecuente porque la gente usa “C/C++” como si significara algo específico y como si supieran lo que significa, lo que genera mucha confusión y miseria. La gente debería preguntarse “¿Qué es C/C++?” y luego, reflexionando, deje de usar el término. Hace daño.

No existe ningún lenguaje llamado “C/C++”. La frase suele ser utilizada por personas que no tienen ni idea de programación (por ejemplo, personal de recursos humanos y malos directivos). Alternativamente, lo utilizan personas que simplemente no conocen C++ (y, a menudo, tampoco C). Cuando lo utilizan los programadores, normalmente indica una actitud de “C++ es C con algunas funciones útiles y muchas funciones complicadas inútiles agregadas”. A menudo, ese es el punto de vista de las personas a quienes les gusta escribir sus propias cadenas y tablas hash con poco conocimiento de la biblioteca estándar más allá de printf y memcpy. Hay personas que se ciñen a un subconjunto restringido de C++ por razones perfectamente válidas, pero (hasta donde he notado) no son las personas que dicen “C/C++”.

Utilizo C/C++ sólo en frases como “compatibilidad C/C++” y “comunidad C/C++”.


¿Cuándo se inventó C++?

Empecé a trabajar en lo que se convirtió en C++ en 1979. La versión inicial se llamó “C con clases”. La primera versión de C++ se utilizó internamente en AT&T en agosto de 1983. El nombre “C++” se utilizó a finales de ese año. La primera implementación comercial se lanzó en octubre de 1985, al mismo tiempo que la publicación de la primera edición de The C++ Programming Language . Las plantillas y el manejo de excepciones se incluyeron más tarde en la década de 1980 y se documentaron en The Annotated C++ Reference Manual y The C++ Programming Language (2.ª edición) . El primer estándar ISO C++ fue C++98, como se describe en El lenguaje de programación C++ (3.ª edición) .

La definición actual de C++ El estándar ISO C++ 2011 descrito en El lenguaje de programación C++ (4ª edición) .

Puede encontrar una línea de tiempo más completa y explicaciones más detalladas en El diseño y evolución de C++ y Una historia de C++: 1979-1991 y Evolución de un lenguaje en y para el mundo real: C++ 1991-2006 .


¿Por qué inventaste C++?

Quería escribir programas de sistemas eficientes en los estilos fomentados por Simula67. Para hacerlo, agregué a C funciones para una mejor verificación de tipos, abstracción de datos y programación orientada a objetos. El objetivo más general era diseñar un lenguaje en el que pudiera escribir programas que fueran a la vez eficientes y elegantes. Muchos idiomas te obligan a elegir entre esas dos alternativas.

Las tareas específicas que me llevaron a comenzar a diseñar e implementar C++ (inicialmente llamado “C con clases”) tuvieron que ver con la distribución de las instalaciones del sistema operativo a través de una red.

Puede encontrar explicaciones más detalladas en El diseño y evolución de C++ . Véase también Una historia de C++: 1979-1991 y Evolución de un lenguaje en y para el mundo real: C++ 1991-2006 .


¿Por qué AT&T apoyó el desarrollo de C++?

Cuando desarrollé C++ por primera vez, AT&T creó sistemas de mayor complejidad y con mayores requisitos de confiabilidad que la mayoría de las organizaciones. En consecuencia, tuvimos que influir en el mercado y ayudar a establecer estándares que satisfagan nuestras necesidades; de lo contrario, no tendríamos las herramientas para construir nuestros sistemas. Si se la deja a su suerte, “la industria” creará lenguajes y herramientas para abordar los problemas “promedio”. De manera similar, los profesores tienden a centrarse en lenguajes y herramientas que sirven bien a estudiantes e investigadores, incluso si no se adaptan a las tareas más exigentes.

En el momento en que desarrollé C++ – y antes de eso, cuando Ken Thompson y Dennis Ritchie desarrollaron Unix y C – AT&T era probablemente el mayor usuario civil (y consumidor de) herramientas de software del mundo. Entonces, probablemente utilizamos una gama más amplia de sistemas, desde los procesadores integrados más pequeños hasta las supercomputadoras y sistemas de procesamiento de datos más grandes. Eso dio prioridad a los sistemas que eran aplicables en muchas culturas técnicas y en muchas plataformas. C y C++ se diseñaron teniendo en cuenta esas exigencias.

Por lo tanto, la generalidad es esencial y se considera que las características patentadas limitan la elección de plataformas y proveedores. Como consecuencia, AT&T fue y es un importante defensor de los estándares formales (por ejemplo, ISO C e ISO C++).

En realidad, AT&T ganó suficiente dinero con Cfront, mi compilador de C++ original, para pagar varias veces el desarrollo de C++.


¿Tienes C++?

No. Si alguien “posee C++”, debe ser el ISO. AT&T otorgó los derechos del manual de C++ que escribí a la ISO. El estándar ISO C++ tiene derechos de autor de ISO.

Los proveedores de compiladores no me pagan regalías a mí ni a AT&T por C++, y los estándares ISO son especificaciones destinadas a ser utilizadas sin regalías por todos (una vez que hayan pagado a ISO o a un comité de estándares nacional por su copia del estándar). Los compiladores individuales son propiedad de sus respectivos vendedores/proveedores.

“Pero alguien de SCO afirmó que posee C++”; ¿no es así? Es una completa basura. Vi esa entrevista. El tipo de SCO claramente no tenía idea de qué era C++ y se refirió a él como “los lenguajes C++”. Como máximo, SCO puede poseer una versión de Cfront de 15 años de antigüedad y muy desactualizada, mi compilador de C++ original. Tuve cuidado de no patentar ni registrar nada que tuviera que ver con C++. Esa es una de las razones por las que escribimos “C++” simple y no “C++(tm)”. El estándar C++ no está sujeto a patentes; el comité también lo comprobó cuidadosamente.


¿De dónde viene el nombre “C++”?

Capítulo 3 de D&E : “Elegí C++ porque era breve, tenía buenas interpretaciones y no tenía la forma “adjetivo C”.’ En C, ++ puede, según el contexto, leerse como “siguiente”. “sucesor” o “incremento”, aunque siempre se pronuncia “más más”. El nombre C++ y su subcampeón ++C son fuentes fértiles para chistes y juegos de palabras, casi todos conocidos y apreciados antes de que se eligiera el nombre. El nombre C++ fue sugerido por Rick Mascitti. Se utilizó por primera vez en diciembre de 1983 cuando se editó en las copias finales de [Stroustrup,1984] y [Stroustrup,1984c].

Capítulo 1 de TC++PL : “El nombre C++ (pronunciado “ver plus plus”) fue acuñado por Rick Mascitti en el verano de 1983. El nombre significa la naturaleza evolutiva de los cambios de C; “++” es el operador de incremento de C. El nombre ligeramente más corto “C+” es un error de sintaxis; también se ha utilizado como nombre de un idioma no relacionado. Los conocedores de la semántica de C consideran que C++ es inferior a ++C. El lenguaje no se llama D porque es una extensión de C y no intenta solucionar los problemas eliminando funciones. Para otra interpretación más del nombre C++, consulte el apéndice de [Orwell,1949]”.

La “C” en C++ tiene una larga historia. Naturalmente, es el nombre del lenguaje que diseñó Dennis Ritchie. El antepasado inmediato de C fue un descendiente interpretado de BCPL llamado B diseñado por Ken Thompson. BCPL fue diseñado e implementado por Martin Richards de la Universidad de Cambridge mientras visitaba el MIT en el otro Cambridge. BCPL, a su vez, era Basic CPL, donde CPL es el nombre de un lenguaje de programación bastante grande (para su época) y elegante desarrollado conjuntamente por las universidades de Cambridge y Londres. Antes de que los londinenses se unieran al proyecto, la “C” significaba Cambridge. Más tarde, “C” significaba oficialmente Combinado. Extraoficialmente, “C” significaba Christopher porque Christopher Strachey era el principal poder detrás de la CPL.”


¿Qué lenguaje usaste para escribir C++?

El primer compilador de C++ (Cfront) fue escrito en C++. Para construir eso, primero usé C para escribir un preprocesador “C con clases” a C. “C con clases” era un dialecto de C que se convirtió en el ancestro inmediato de C++. Ese preprocesador tradujo construcciones “C con clases” (como clases y constructores) a C. Era un preprocesador tradicional que no entendía todo el lenguaje, dejaba la mayor parte de la verificación de tipos para que la hiciera el compilador de C y traducía individualmente. construye sin conocimiento completo. Luego escribí la primera versión de Cfront en “C con clases”.

Cfront era un compilador tradicional que realizaba una verificación completa de sintaxis y semántica del código fuente C++. Para eso, tenía un analizador completo, construyó tablas de símbolos y construyó una representación de árbol interna completa de cada clase, función, etc. También hizo algunas optimizaciones a nivel de fuente en su representación de árbol interna de construcciones de C++ antes de generar C. La versión que generó C, no dependió de C para ninguna verificación de tipo. Simplemente usó C como ensamblador. El código resultante fue increíblemente rápido. Para obtener más información, consulte D&E .


¿Realmente no entendiste lo que estabas haciendo?

Éste parece muy popular. O más bien, parece popular afirmar que no tenía idea de que el éxito de C++ es algún tipo de accidente. Sí, esas declaraciones me molestan, porque desestiman mi trabajo durante décadas y el arduo trabajo de muchos de mis amigos.

Primero, seamos perfectamente claros: no, no anticipé el éxito arrollador de C++ y no, no preví todas las técnicas utilizadas con C++ o todas las aplicaciones de C++. ¡Por supuesto que no!

Sin embargo, afirmaciones como estas son muy engañosas:

  • ¡Bjarne no entiende C++!
  • ¡Bjarne no anticipó la RAII y la destrucción determinista!
  • ¡Bjarne no anticipó la metaprogramación de plantillas!

Estas preguntas frecuentes surgieron al ver estas y varias más de su tipo hoy.

Describí los criterios para el diseño y la implementación de C++. Apunté explícitamente a la generalidad: “No estoy interesado en un lenguaje que sólo pueda hacer lo que puedo imaginar” y a la eficiencia “una instalación no sólo debe ser útil, sino que debe ser asequible”. Sugiero que los que dudan lean El diseño y evolución de C++ y mis artículos HOPL2 y HOPL3 (estos son artículos revisados ​​por pares). En cuanto a la destrucción determinista, estuvo en “C con Clases” en la primera semana o dos (1979). Retrasé la introducción de excepciones en C++ durante medio año hasta que descubrí RAII (1988). RAII es una parte integral y necesaria del mecanismo de excepción de C++.

Me sorprendió mucho cuando Jeremy Siek me mostró por primera vez el tiempo de compilación si luego se convertía en std::conditional , pero había apuntado a la generalidad (y obtuve los límites de traducción del módulo de integridad de Turing). Me opuse a las restricciones a C++ inmediatamente cuando Erwin Unruh presentó lo que se cree ampliamente que es la primera plantilla de metaprograma al grupo de trabajo de evolución del comité de Normas ISO. Para acabar con la metaprogramación de plantillas, todo lo que habría tenido que hacer era no decir nada. En cambio, mi comentario fue del tipo “¡Guau, eso es genial! No debemos comprometerlo. Podría resultar útil”. Como todas las ideas poderosas, la metaprogramación de plantillas puede usarse mal o en exceso, pero eso no implica que la idea fundamental del cálculo en tiempo de compilación sea mala. Y como todas las ideas poderosas, las implicaciones y técnicas surgieron con el tiempo con contribuciones de muchas personas.

Las becas implican más que una mirada a Wikipedia, una búsqueda rápida en Google y un par de publicaciones en un blog. La invención implica mucho más que dar una simple lista de implicaciones. Los principios fundamentales y las pautas de diseño son esenciales. Mi parte del diseño de C++ abrió la posibilidad para que muchos contribuyeran, y si miras mis escritos y publicaciones, verás que me esfuerzo por dar crédito (por ejemplo, consulta las secciones de referencia de mis preguntas frecuentes sobre C++11 ) o el secciones de historia de mis libros .

Y no, no soy un diccionario ambulante de C++. No tengo todos los detalles técnicos en mi cabeza en todo momento. Si hiciera eso, sería un programador mucho peor. Mantengo los puntos principales claros en mi cabeza la mayor parte del tiempo y sé dónde encontrar los detalles cuando los necesito. Por ejemplo:

  • TC++PL
  • Las páginas de inicio del comité ISO C++ .
  • isocpp.org .

¿Por qué C++ no tiene recolección de basura?

Si desea la recolección automática de basura, existen buenos recolectores de basura comerciales y de dominio público para C++. Para aplicaciones donde la recolección de basura es adecuada, C++ es un excelente lenguaje de recolección de basura con un rendimiento que se compara favorablemente con otros lenguajes de recolección de basura. Consulte El lenguaje de programación C++ para obtener información sobre la recolección automática de basura en C++. Véase también Hans-J. Sitio de Boehm para recolección de basura C y C++ .

Además, C++ admite técnicas de programación que permiten que la gestión de la memoria sea segura e implícita sin un recolector de basura . Considero que la recolección de basura es una última opción y una forma imperfecta de manejo para la gestión de recursos. Eso no significa que nunca sea útil, sólo que existen mejores enfoques en muchas situaciones.

C++ 11 ofrece una ABI de GC.

No me gusta la basura. No me gusta tirar basura. Mi ideal es eliminar la necesidad de un recolector de basura al no producir basura. Eso ahora es posible. Herramientas que apoyan y hacen cumplir las técnicas de programación que logran lo que se están produciendo. Para obtener una descripción general, consulte Una breve introducción al modelo de C++ para la seguridad de tipos y recursos. .


¿Por qué C++ no tiene una GUI?

C++ tiene muchas GUI comerciales y de código abierto (por ejemplo , Gtkmm , SmartWin++ , V C++ GUI , FLTK y Qt ). En particular, cada proveedor de plataforma proporciona una biblioteca C++ para acceder a su GUI. El problema es que no tiene una GUI estándar y, de hecho, ese es un problema importante.

Tenga en cuenta que proporcionar una GUI es un problema tanto técnico como político. Hay muchas GUI con muchos usuarios y, en general, no les gustaría que se declarara estándar alguna otra GUI. De todos modos, el comité de estándares no tiene los recursos para construir una GUI nueva y mejor.


¿Por qué C++ no admite subprocesos?

C++ 11 ofrece subprocesos.


¿C++ está en declive?

No, no lo creo. El uso de C++ parece estar disminuyendo en algunas áreas y aumentando en otras. Si tuviera que adivinar, sospecharía una disminución neta en algún momento durante 2002-2004 y un aumento neto en 2005-2007 y nuevamente en 2010-2011, pero dudo que alguien lo sepa realmente. La mayoría de las medidas populares básicamente miden el ruido y deberían informar sus resultados en decibelios en lugar de “popularidad”. Una encuesta profesional realizada en 2015 estimó que el número de programadores de C++ era de 4,4 millones. Muchos de los usos principales de C++ se encuentran en infraestructura (telecomunicaciones, banca, sistemas integrados, etc.) donde los programadores no van a conferencias ni describen su código en público. Muchas de las aplicaciones C++ más interesantes e importantes pasan desapercibidas, no están a la venta al público como productos de programación y nunca se menciona su lenguaje de implementación. Algunos ejemplos son Google y los números de teléfono “800”. Si hubiera pensado en un logo “C++ inside” en 1985, el mundo de la programación podría haber sido diferente hoy.

Una cosa simple que confunde muchas discusiones sobre el uso/popularidad del lenguaje es la distinción entre medidas relativas y absolutas. Por ejemplo, digo (en 2011) que el uso de C++ está creciendo cuando veo que la población de usuarios crece en 200.000 programadores, de 3,1 millones a 3,3 millones. Sin embargo, alguien más puede afirmar que “C++ está muriendo” porque su “popularidad” ha caído del 16 por ciento al 11 por ciento del número total de programadores. Ambas afirmaciones podrían ser simultáneamente ciertas a medida que el número de programadores continúa creciendo y, especialmente, lo que se considera programación continúa cambiando. Creo que C++ es más que mantenerse firme en sus dominios centrales tradicionales, como infraestructura, programación de sistemas, sistemas integrados y aplicaciones con serias limitaciones de tiempo y/o espacio y/o consumo de energía. Vea también mi entrevista con DevX .


¿Qué se está haciendo para mejorar C++?

Los implementadores mejoran continuamente sus compiladores , bibliotecas y herramientas. En los últimos cinco años se han producido mejoras muy significativas en la calidad. Esto es lo que ayuda más directa e inmediatamente a las personas; eso, y la gran cantidad de bibliotecas y herramientas patentadas y de código abierto que la comunidad C++ produce continuamente. Consulte mi página de C++ para ver ejemplos.

El primer estándar ISO C++ fue ratificado en 1998. La próxima versión C++11 está completa y en envío. Puede encontrar artículos que describen C++11 en mi página de publicaciones y todos los documentos relacionados con el nuevo estándar en las páginas de inicio del comité ISO C++ . Mi artículo HOPL-iii sobre los últimos 15 años de evolución de C++ puede ser la mejor explicación de lo que se está haciendo y por qué. Una entrevista reciente contiene listas de nuevas características del lenguaje y bibliotecas estándar.

Al considerar la evolución de C++, vale la pena recordar que el objetivo no es agregar la mayor cantidad de características nuevas, sino mejorar C++ en sus dominios de aplicaciones clave, incluida la programación de sistemas y la creación de bibliotecas, sin romper el código antiguo (hay miles de millones). de líneas de C++ “por ahí”).


¿Por qué el código generado para el programa “Hola mundo” es diez veces mayor para C++ que para C?

No está en mi máquina y no debería estar en la tuya. Incluso he visto la versión C++ del programa “hola mundo” más pequeña que la versión C. En 2004, probé el uso de gcc -O2 en Unix y las dos versiones (iostreams y stdio) arrojaron tamaños idénticos. No existe ningún motivo lingüístico por el que una versión deba ser más grande que la otra. Todo es una cuestión de cómo un implementador organiza las bibliotecas estándar (por ejemplo, enlaces estáticos versus enlaces dinámicos, soporte local predeterminado versus soporte local habilitado a través de una opción, etc.). Si una versión es significativamente más grande que la otra, informe el problema al implementador de la versión más grande.


¿Cómo puede un lenguaje heredado como C++ competir con lenguajes modernos y avanzados?

Naturalmente, llamar a C++ un lenguaje heredado muestra un sesgo (consulte el código heredado ). Aparte de eso, la gente suele pensar en Java o C# cuando hace esa pregunta. No compararé C++ con esos lenguajes , pero puedo señalar que “moderno” no significa necesariamente “mejor”, y que tanto Java como C# están arraigados en el estilo de programación orientada a objetos de los años 1980 en mayor medida que el C++ temprano.

Desde 1987 aproximadamente, el foco del desarrollo del lenguaje C++ y sus estilos de programación asociados ha sido el uso de plantillas, polimorfismo estático, programación genérica y programación multiparadigma. Esto está mucho más allá del alcance de los tan publicitados lenguajes propietarios. Otra diferencia clave es que C++ admite tipos definidos por el usuario en la misma medida que los tipos integrados. Esto, especialmente en combinación con el uso de plantillas, constructores y destructores, permite al programador de C++ utilizar técnicas de programación y diseño que (en mi opinión) son más avanzadas que las admitidas en los lenguajes con los que se compara más a menudo C++; por ejemplo, ver RAII .

El C++ estándar y los estilos de diseño y programación que admite tienen una deuda con los lenguajes funcionales, especialmente con el ML. Las primeras variantes de los mecanismos de deducción de tipos de ML fueron (junto con muchas otras cosas) parte de la inspiración de las plantillas. Algunas de las técnicas de programación funcional más efectivas fueron parte de la inspiración de STL y el uso de objetos de función en C++. Por otro lado, la comunidad funcional perdió el tren con la programación orientada a objetos, y pocos de los lenguajes y herramientas de esa comunidad se beneficiaron de la experiencia madura del uso industrial a gran escala.

Claramente, no creo que la recolección de basura sea la única característica definitoria de “avanzado” en el contexto de los lenguajes de programación. En particular, tenga en cuenta que C++ brinda soporte para técnicas de administración de memoria efectivas y eficientes que pueden eliminar las fugas de recursos sin el uso de un recolector de basura. Si no está de acuerdo, puede empezar a utilizar un recolector de basura para C++; hay buenos disponibles.


¿Qué es la “programación multiparadigma”?

La programación multiparadigma es una forma elegante de decir “programar usando más de un estilo de programación, cada uno para su mejor efecto”. Por ejemplo, usar programación orientada a objetos cuando se requiere resolución en tiempo de ejecución entre diferentes tipos de objetos y programación genérica cuando se requiere resolución en tiempo de ejecución entre diferentes tipos de objetos. la seguridad de tipos y el rendimiento en tiempo de ejecución son muy importantes. Naturalmente, la principal fortaleza de la programación multiparadigma está en los programas donde se utiliza más de un paradigma (estilo de programación), por lo que sería difícil obtener el mismo efecto componiendo un sistema a partir de partes escritas en lenguajes que admitan diferentes paradigmas. Encuentro que los casos más convincentes de programación multiparadigma se encuentran cuando se utilizan técnicas de diferentes paradigmas en estrecha colaboración para escribir código que sea más elegante y más fácil de mantener de lo que sería posible dentro de un solo paradigma. Un ejemplo simple es el recorrido de un contenedor de objetos de tipo polimórfico tipado estáticamente:

Aquí, Shape será una clase base abstracta que definirá la interfaz para una jerarquía de formas geométricas. Este ejemplo se generaliza fácilmente a cualquier contenedor de biblioteca estándar:

El libro de Jim Coplien “Diseño multiparadigma para C++” (Addison Wesley, 1998) explora el uso de múltiples paradigmas en el contexto del diseño y los métodos de diseño.

Necesitamos un término mejor, más descriptivo, para reemplazar “multiparadigma”.


¿Por qué C++ es tan GRANDE?

C++ no es tan grande como algunas personas imaginan. No es un lenguaje pequeño diseñado para ser un lenguaje mínimo para la enseñanza, pero tampoco lo son los lenguajes con los que la gente lo compara más a menudo, como C, Java, C#. Ellos también son enormes en comparación con Pascal, como lo definió originalmente el Dr. Wirth, creo que por buenas razones. El mundo de la programación es mucho más complejo hoy que hace 30 años, y los lenguajes de programación modernos lo reflejan.

El estándar C++ es de 1151 páginas; eso incluye 430 páginas de definición de lenguaje y 770 páginas de descripción de biblioteca estándar. El tamaño de la definición del lenguaje está dentro del 5 % de las descripciones de los lenguajes de Java y C# (medido por el recuento de páginas). De manera similar, TC++PL tiene 1360 páginas; de ellos, 750 están dedicados a instalaciones lingüísticas y técnicas de programación; el resto habla de bibliotecas, etc.

C++ admite directamente (es decir, en el lenguaje) lo que otros lenguajes admiten a través de bibliotecas, por lo que la parte del lenguaje será relativamente mayor. Por otro lado, si desea escribir una “aplicación moderna típica”, debe considerar las interfaces del sistema operativo, la GUI, las bases de datos, las interfaces web, etc., la suma de las características del lenguaje, las bibliotecas y las convenciones y estándares de programación que debe familiarizarse con el lenguaje de programación enano. Aquí, el tamaño de C++ puede ser una ventaja en la medida en que soporta mejor buenas bibliotecas.

Finalmente, se acabaron los días en los que un programador novato podía conocer todo un lenguaje, al menos para los lenguajes de uso industrial generalizado. Pocas personas saben “todo C” o “todo Java” y ninguno de ellos es novato. De ello se deduce que nadie debería tener que disculparse por el hecho de que los principiantes no sepan todo C++. Lo que debe hacer, en cualquier idioma, es elegir un subconjunto, comenzar a escribir código y aprender gradualmente más sobre el idioma, sus bibliotecas y sus herramientas. Para conocer mi sugerencia sobre cómo los principiantes pueden abordar C++, consulte Programación: principios y práctica con C++ .


¿Qué opinas de EC++?

EC++ es un (casi) subconjunto de C++ que carece de excepciones, plantillas, espacios de nombres, soporte RTTI, herencia múltiple, etc., definido por un “consorcio industrial”. No estoy a favor de subconjuntos de lenguas ni de dialectos. Especialmente no me gustan los subconjuntos que no pueden soportar la biblioteca estándar, por lo que los usuarios de ese subconjunto deben inventar sus propias bibliotecas básicas incompatibles. Temo que un subconjunto definido de C++ pueda dividir a la comunidad de usuarios y causar acritud (31/3/1999: acabo de ver un anuncio que utilizaba gráficos vívidos para indicar cómo EC++ redujo la “grasa” (es decir, el espacio de memoria) al abolir, entre otras cosas cosas: espacios de nombres, plantillas y cadenas estándar de C++. ¡Suspiro!). Prefiero firmemente que el trabajo sobre “estándares” se realice en un foro abierto (como ISO o una organización nacional de normalización).

Para obtener una discusión sobre cómo los implementadores de sistemas integrados pueden abordar los problemas de rendimiento utilizando C++ estándar (mejor que usando dialectos), consulte el informe del comité ISO C++ sobre rendimiento . Hasta donde yo sé, EC++ está muerto (2004), y si no lo está, debería estarlo.

Para ver cómo se puede utilizar ISO C++ para una programación seria de sistemas integrados, consulte los estándares de codificación C++ para vehículos aéreos JSF .


¿C++ obtuvo sus conceptos orientados a objetos de Smalltalk?

No. C++ obtuvo las nociones clave de clases, clases derivadas y funciones virtuales (en otras palabras, las nociones de encapsulación, herencia y polimorfismo) de Simula tal como lo hizo Smalltalk. En términos de relaciones familiares, C++ y Smalltalk son hermanos.


¿Es C++ un lenguaje orientado a objetos?

C++ es un lenguaje de programación multiparadigma que admite estilos de programación orientados a objetos y otros estilos útiles. Si lo que buscas es algo que te obligue a hacer las cosas exactamente de una manera, C++ no lo es. No existe una forma correcta de escribir todos los programas, e incluso si la hubiera, no habría forma de obligar a los programadores a utilizarla.

Dicho esto, escribir programas estilo C en C++ no es para la mayoría de las aplicaciones un uso óptimo de C++. Para ser un programador de C++ realmente eficaz, debe utilizar los mecanismos de abstracción y el sistema de tipos de una manera que se ajuste razonablemente a su intención. Intentar ignorar o derrotar el sistema de tipos C++ es una experiencia de lo más frustrante.

Escribir código estilo Java en C++ puede ser tan frustrante y subóptimo como escribir código estilo C en C++.

Para una discusión más detallada consulte cualquiera de mis artículos de descripción general o de estilo de mi bibliografía. En particular, consulte mi artículo de OOPSLA “Por qué C++ no es sólo un lenguaje de programación orientado a objetos”.


¿Realmente has dicho eso?

Ver Cotizaciones .


¿Realmente le diste una entrevista al IEEE?

¿En el que confesaste que C++ fue creado deliberadamente como un lenguaje horrible para escribir código que no se puede mantener y aumentar los salarios de los programadores?

Por supuesto que no. Lea la entrevista real del IEEE .


¿Qué es el “código heredado”?

“Código heredado” es un término que se utiliza a menudo de manera despectiva para caracterizar el código escrito en un lenguaje o estilo que (1) el hablante/escritor considera obsoleto y/o (2) compite con algo vendido/promovido por el hablante/escritor. El “código heredado” a menudo difiere de la alternativa sugerida en que realmente funciona y escala.


¿Se sigue duplicando cada año el número de usuarios de C++?

No. Durante 1980-1991, el número de usuarios se duplicó cada siete meses y medio (ver El diseño y evolución de C++ ). Sin embargo, simplemente no hay suficientes programadores para sostener eso. De las pocas cifras que puedo obtener (ventas de compiladores, ventas de libros, cargas de trabajo de consultores que conozco, IDC, etc.), estimo que la tasa de crecimiento es de un pequeño porcentaje. Estable y definitivamente positivo . IDC estimó que en 1996 se vendieron 1,2 millones de implementaciones de C++. Su estimación de 2001 del número de programadores de C++ era “alrededor de 3 millones”; su cifra en 2004 era “más de 3 millones”. Una encuesta profesional realizada en 2015 encontró 4,4 millones de programadores de C++. Esto parece plausible e indica un crecimiento continuo.


¿Alguien usa C++ hoy en día?

Sí, muchos lo hacen. Hay demasiados usuarios de C++ para contarlos efectivamente, pero el número es de millones. C++ es compatible con todos los principales proveedores . Para ver ejemplos de uso de C++, consulte mi muestra de aplicaciones .


¿Por qué no se utiliza C++ para los sistemas operativos?

Lo es, y lo ha sido durante más de una década; consulte mi lista de aplicaciones C++ . Un ejemplo reciente es Cloudius .


¿Esperaba que C++ tuviera tanto éxito?

Por supuesto que no. La tasa de éxito de los lenguajes de programación de propósito general es extremadamente pequeña. Lo sabía y sabía que las posibilidades de éxito se veían afectadas por la influencia del marketing, que yo no tenía.

C++ se diseñó e implementó inicialmente como un conjunto de funciones generales que abordaban algunos problemas específicos que yo y mis colegas enfrentamos. La generalidad -y la eficiencia- de las instalaciones proporcionadas resultaron satisfacer necesidades mucho más amplias de las que había previsto. El énfasis en las facilidades generales, en lugar de proporcionar soluciones específicas a problemas específicos, se ha mantenido en C++ y ha servido bien a su comunidad, ya que los problemas específicos que enfrenta la comunidad han cambiado a lo largo de los años.


¿Qué es una buena certificación para programadores de C++?

Hasta donde yo sé, no existe un buen programa de certificación para programadores de C++. Eso es una lástima. Un buen programa de certificación sería de gran utilidad. Sin embargo, C++ carece de la organización central que produciría un programa de certificación sólido, y un programa de certificación sin autoridad o centrado en la sintaxis sería peor que inútil.


¿Por qué fuiste a trabajar a Morgan Stanley?

Sentí que era hora de volver a la industria. Me perdí los desafíos de proyectos a gran escala del mundo real con consecuencias reales en caso de éxito o fracaso. La academia estaba empezando a parecerme un poco cómoda y una “torre de marfil” (esa no es la forma en que es la academia para los profesores más jóvenes y los profesores adjuntos; esos necesitan y merecen mucho más apoyo del que reciben). La división de tecnología de Morgan Stanley tiene una enorme variedad de desafíos en materia de informática y una gran cantidad de gente inteligente, bien educada y sorprendentemente (dada la popular reputación de la gente que trabaja para “Wall Street”) agradable. Morgan Stanley tiene un uso muy serio de C++. Además, me ocupo de la estandarización de C++ (C++17 está en camino) e investigo un poco en mi calidad de profesor en la Universidad de Columbia y la Universidad Texas A&M . Ya era hora de regresar al noreste y con mi familia allí.

PD. Trabajo para Morgan Stanley, no para JP Morgan. Morgan Stanley es un banco bastante regulado , más que una “institución financiera” genérica, y, en mi opinión, una de las instituciones financieras administradas de manera más ética.

PPP. Simplemente no se puede gestionar una sociedad moderna sin bancos.


¿Por qué fuiste a trabajar a la Universidad Texas A&M?

Se había acabado el vapor de Bell Labs y sus sucesores, AT&T Labs y Lucent Bell Labs. Simplemente ya no era lo que solía ser. Tenía (y tengo) amigos en TAMU y pensé que era un buen lugar para aprender las diversas habilidades de la vida académica. Para empezar, la investigación académica es bastante diferente de la investigación industrial a la que estaba acostumbrado. De manera similar, enseñar a estudiantes de primer año y graduados es muy diferente de enseñar a profesionales. También ayudé a construir el Departamento de Ingeniería y Ciencias de la Computación . Todavía estoy asociado con TAMU como Profesor Universitario Distinguido.

PD. Universidad Texas A&M! = Universidad de Texas.


¿Por qué fuiste a trabajar a los laboratorios Bell?

Porque podría. En la década de 1980 (y años antes y después), no había ningún lugar en la tierra como este. Todavía no lo hay. Bell Labs era el principal centro de investigación de ingeniería y ciencias aplicadas del mundo. Era un lugar de trabajo muy emocionante y desafiante, con colegas extraordinarios. Formé parte del Centro de Investigaciones en Ciencias de la Computación . Dejé AT&T Labs (uno de los dos sucesores de AT&T Bell Labs) en buenos términos y estuve asociado con AT&T como miembro de AT&T durante otra década.


¿En qué trabaja ahora?

Unas preguntas frecuentes mejores 🙂

En serio, estoy buscando formas fundamentales de mejorar las herramientas y técnicas que utilizamos para construir grandes sistemas del mundo real. Una parte de mi trabajo es C++11 .


¿Qué es C++?

C++ es un lenguaje de programación de propósito general con un sesgo hacia la programación de sistemas que

  • es una mejor C
  • soporta la abstracción de datos
  • soporta programación orientada a objetos
  • soporta programación genérica

Está definido por un estándar ISO , ofrece estabilidad durante décadas y cuenta con una comunidad de usuarios grande y animada. Véase también El lenguaje de programación C++ y La evolución de un lenguaje en y para el mundo real: C++ 1991-2006 .


¿Dónde puedo obtener información sobre los antecedentes de C++?

¿Sobre el diseño de C++? ¿Sobre la historia de C++?

Mire mis artículos para HOPL-2 y HOPL-3 ; HOPL significa “Historia de los lenguajes de programación”, la principal conferencia sobre ese tema, patrocinada por la ACM. Estos son artículos fuertemente revisados ​​por pares. Para obtener aún más información, consulte mi libro The Design and Evolution of C++ y el prefacio de la traducción japonesa de 2006 de D&E , que trae la información hasta 2006. Además, muchas de mis entrevistas abordan cuestiones de antecedentes, diseño e historia de C++. .


¿Es cierto que…?

Me vienen muchas preguntas en forma de afirmaciones.

  • C++ es de bajo nivel (?)
  • C++ es demasiado lento para trabajos de bajo nivel (?)
  • C++ es útil sólo si escribes código verdaderamente orientado a objetos(?)
  • El C++ moderno es pura programación genérica y metaprogramación de plantillas (?)
  • C++ está diseñado por Microsoft(?)

A menudo, la persona que plantea uno de estos puntos considera la afirmación como un hecho (pero ninguna de estas afirmaciones es cierta); a veces, hay un signo de interrogación implícito. Entonces,

  • ¿C++ es de bajo nivel? No. C++ ofrece funciones tanto de bajo como de alto nivel. C++ tiene partes de bajo nivel, como punteros, matrices y conversiones. Estas funciones (casi idénticas a las que ofrece C) son esenciales (de una forma u otra) para el trabajo cercano al hardware. Por lo tanto, si desea funciones de lenguaje de bajo nivel, sí, C++ le proporciona un conjunto de funciones bien probadas. Sin embargo, cuando no desea utilizar funciones de bajo nivel, no necesita utilizar las funciones de C++ (directamente). En su lugar, puede confiar en instalaciones de nivel superior, incluidas las bibliotecas. Por ejemplo, si no desea utilizar matrices y punteros, las cadenas y contenedores de biblioteca estándar son (mejores) alternativas en muchos casos. Si utiliza sólo instalaciones de bajo nivel, es casi seguro que está perdiendo tiempo y complicando el mantenimiento sin ventajas de rendimiento (consulte Aprendizaje de C++ estándar como nuevo lenguaje ). También es posible que sus sistemas estén expuestos a ataques (por ejemplo, desbordamientos de búfer).
  • ¿C++ es demasiado lento para trabajos de bajo nivel? No. Si puede permitirse el lujo de usar C, puede permitirse el lujo de usar C++, incluso las funciones de nivel superior de C++ donde necesita su funcionalidad. Consulte Abstracción y el modelo de máquina C++ y el Informe técnico sobre rendimiento del comité de estándares ISO C++ .
  • ¿C++ es útil sólo si escribes código verdaderamente orientado a objetos? No. Es decir, “no” para casi cualquier definición razonable de “orientado a objetos”. C++ proporciona soporte para una amplia variedad de necesidades, no sólo para un estilo o un tipo de aplicación. De hecho, en comparación con C, C++ proporciona más soporte para tareas de programación muy simples. Por ejemplo, la biblioteca estándar y otras bibliotecas simplifican radicalmente muchas tareas que de otro modo serían tediosas y propensas a errores. C++ se usa ampliamente para aplicaciones de gran tamaño , pero también brinda beneficios incluso para tareas de programación pequeñas.
  • ¿El C++ moderno es todo programación genérica y metaprogramación de plantillas? No. C++ admite varias técnicas de programación útiles , incluida la programación procedimental tradicional, la programación orientada a objetos y la programación genérica. Ninguno de estos es mejor que todos los demás para todos los usos y, por lo general, la solución más eficaz a un problema del mundo real implica una combinación de técnicas.
  • ¿C++ está diseñado por Microsoft? No. Originalmente diseñé e implementé C++ y, junto con el comité de estándares ISO C++, refiné su definición . Microsoft ha asumido un papel activo y en gran medida positivo en esta estandarización, al igual que Apple, GNU, IBM, Sun y muchos otros. Al igual que otros, por ejemplo Apple, Microsoft intenta ayudar/bloquear a sus usuarios con extensiones propietarias (en particular, Microsoft C++/CLI ).

¿Qué opinas de Impulso?

Boost es una colección grande y en expansión de bibliotecas diseñadas para funcionar bien con la biblioteca estándar ISO C++. Contiene muchas bibliotecas extremadamente útiles y bien diseñadas, como asio, filesystem, regex y thread (disculpas por no intentar identificar bibliotecas más útiles; simplemente hay demasiadas). Una biblioteca, TR1, contiene una buena aproximación de los nuevos componentes de la biblioteca estándar de C++11.

Las bibliotecas de Boost tienen conjuntos de pruebas, documentación, han sido probadas en múltiples sistemas y están revisadas por pares.

Sin embargo, tengo dos problemas con Boost, que espero que se resuelvan eventualmente:

  • Es demasiado difícil descargar y utilizar una sola biblioteca Boost; las bibliotecas parecen demasiado acopladas, lo que dificulta la elección.
  • Algunas de las bibliotecas son demasiado inteligentes para mi gusto. A veces coinciden generalidad y sencillez; En Boost, el equilibrio, en mi opinión, con demasiada frecuencia se acerca tanto a la generalidad que los principiantes y los usuarios promedio se pierden.

Dicho esto, suele ser una idea realmente tonta reinventar una rueda que ya ofrece impulso.


¿Qué opinas de la metaprogramación de plantillas?

La metaprogramación de plantillas es un conjunto de poderosas técnicas de programación que, cuando se usan con cuidado y gusto, pueden ayudar a resolver problemas bastante complicados, principalmente relacionados con la arquitectura de sistemas más grandes, su portabilidad y su mantenimiento (consulte Abrahams y Gurtovoy: Metaprogramación de plantillas en C++ y algunas de las bibliotecas Boost .

Como todas las técnicas poderosas, es fácil abusar de ellas. Personalmente, tiendo a usar plantillas principalmente para programación genérica (por ejemplo, definir contenedores y algoritmos sobre contenedores) y para plantillas que generan código bastante obvio basado en argumentos de plantilla (por ejemplo, generar buffers y registrar código de acceso); A eso a veces se le llama programación generativa. Tenga cuidado con la complejidad de las plantillas que escribe o utiliza; es fácil entusiasmarse demasiado y escribir código de plantilla que es demasiado inteligente para ser útil como código de producción mantenible.

Si no le gustan los estilos de programación funcional, es posible que le resulten difíciles de entender los metaprogramas de plantilla. Si le gusta la programación funcional, es posible que la versión de la plantilla le parezca un poco primitiva, pero recuerde que estas plantillas se ejecutan en tiempo de compilación.

El soporte de C++ para la metaprogramación está mejorando. Los conceptos simplificarán drásticamente la programación genérica y harán que gran parte del andamiaje para la metaprogramación de plantillas sea redundante. Además, si lo que desea generar es un valor (por ejemplo, un valor entero), las funciones constexpr son mucho más fáciles de usar (y se compilan más rápido).

Leave a Comment