2010-12-01 8 views
8

No he codificado en C++ durante años. Recientemente descubrí que durante esos años ha cambiado bastante dramáticamente. No estoy seguro de que me gusten los cambios, pero esa es otra discusión.Es nuevo C++ compatible con versiones anteriores

Todavía tengo algún código C++ llamando a mi disco duro. Si lo saqué e intenté compilarlo con un nuevo y agradable compilador de C++, por ejemplo, la última versión de g ++, ¿se compilaría? Sin advertencias (suponiendo que se haya compilado sin advertencias antes)?

Llegué a perder el tiempo con un poco de VC++ 2010 recientemente y encontré que algunas cosas que esperaba funcionar simplemente no funcionaban, y recibí mensajes diferentes según el contexto cuando traté de usar NULL. Pero en una parte de ese código utilicé NULL sin siquiera una advertencia.

Respuesta

8

En general, sí que es compatible con versiones anteriores. Sin embargo, el diablo está en los detalles. Es probable que encuentre cosas en las que las convenciones cambien o que las bibliotecas específicas caigan o desaparezcan.

+0

Recientemente, tuve una probada de "diablo en los detalles" cuando una clase comenzó a necesitar un constructor de movimientos para funcionar correctamente cuando usaba el nuevo C++. De lo contrario, el programa se bloquea dentro del código de C++ 0x STL que utiliza nuevas características. –

13

Depende. Por lo general, los compiladores más nuevos son más compatibles con el estándar, por lo que muchos constructos compilados en compiladores anteriores no se compilan ahora sin corregirlos. Por ejemplo:

for(int i = 0; ...); 
i++; 

compilado en Visual C++ 7, pero no en Visual C++ 9.

+7

Así que C++ en sí mismo es retrocompatible, pero los compiladores que lo implementan no lo son. – foraidt

+3

No entiendo. Ese ejemplo nunca fue válido C++ ..... –

+0

Pero se compilaría en VC2003 con opciones predeterminadas. – Dialecticus

2

Todas las versiones de C++ deben ser compatibles con versiones anteriores.

Aunque puede haber algunos casos inusuales en los que podría haber un problema, p. noexcept en destructos en C++ 0x (aunque esto aún no se ha decidido).

7

NULL es una macro, prefiere usar 0 (o nullptr in C++0x).

No estoy seguro de la antigüedad de su código, pero Visual C++ v6 adolece de limitaciones que dan como resultado código que simplemente no se compilará en los compiladores más nuevos. VS2005 y superior son mucho mejores (en el sentido de más correcto con el estándar contemporáneo de C++).

Sin embargo, no esperaría que fuera una gran cantidad de trabajo obtener el código antiguo compilado. He hecho algunos puertos bastante importantes desde VC6 -> VS2005 y en su mayor parte es cuestión de horas, no días. Quizás una vez que el choque cultural haya desaparecido, esto no parezca tan desalentador. Realmente, VC++ 10 es muy agradable.

+0

solo curiosidad, ¿qué pasa con que NULL sea una macro? – Javier

+1

Alguien más podría hacer esto: '@undef NULL' luego' #define NULL 1'. Un tonto ejemplo, pero esa es una razón por la cual las macros son una mierda. –

+0

@Javier Podría definirse como, por ejemplo, '(void *) 0' en lugar de solo 0, lo que significa que no podría usarlo como un puntero nulo de uso general. Alternativamente, podría estar indefinido y redefinirse a voluntad. –

2

Bueno, sé que gran parte de nuestro viejo código VS6 comenzó a lanzar toneladas de advertencias cuando nos actualizamos a VS 2005 (con advertencias completas, por supuesto, ya que todos deberían trabajar). La mayoría eran buenas cosas, sin embargo, la advertencia de la posible pérdida de información, advirtiendo que algunos tipos pueden ser de 64 bits en lugar de 32 bits como el código de edad era de esperar, etc.

Para su ejemplo específico de NULL, todo esto fuese' t incluso realmente estándar C en el día. Cada compilador acaba de tener un #define que lo establece en 0. Actualmente, se considera más correcto (y claro) a just use 0.

+0

'NULL' no es estándar? Se remonta a C89. Incluso es más antiguo que unos cuantos programadores de C++. – MSalters

+1

Bueno, soy más viejo que eso. Solíamos tener que buscar realmente lo que NULL se definió como para estar seguros. Algunos compiladores lo configuran como cosas raras, y ocasionalmente los archivos fuente de mal comportamiento incluso lo redefinirían. –

2

Los estándares más nuevos de C++ vienen a aclarar cosas, luego toman decisiones sobre qué uso es "más correcto" o aceptado, así que esperaría advertencias. Algunas otras decisiones cambian lo que se puede hacer o no, así que también esperaría errores. Me encontré con la misma situación y tuve que ajustar el código para que compilara. No fue una gran oferta, pero esto fue teniendo en cuenta mi conocimiento de C++. En general, no deberías encontrar grandes problemas.

También hay otras cosas.Por ejemplo, no todos los compiladores implementaron las reglas completas del estándar C++, o tenían errores. Cuando te acostumbras con un compilador, algunos de esos errores o características que faltan pueden pasar desapercibidos para tu compilador, pero pueden causar errores en futuras versiones del mismo compilador.

2

Esa es la razón principal por la que tenemos estándares. No tiene que preocuparse por la compatibilidad, simplemente le dirá al compilador que compile el código como C++ 98 (o 2003).

MSVC lamentablemente es muy malo para admitir los estándares de C++. Poco a poco está mejorando (y es por eso que el código antiguo no se compila, ya que no debería compilar en primer lugar).

+4

No puedo estar de acuerdo con la caracterización de que MSVC es "muy malo" en la conformidad. Ya no más, de todos modos. –

3

El lenguaje en sí no ha cambiado desde que se estandarizó en 1998. Los modismos han cambiado, y los compiladores han mejorado su compatibilidad con el estándar y se vuelven más estrictos con el código no estándar, pero cualquier código C++ estándar compilado en el pasado aún debería compilarse hoy. El código que se basa en características o peculiaridades del compilador no estándar puede no funcionar, pero los compiladores suelen ofrecer opciones de línea de comandos para que acepten código no estándar que solía ser aceptado por versiones anteriores del mismo compilador.

NULL es una macro que se define en <cstddef>. Otros encabezados estándar pueden incluir ese encabezado como un detalle de implementación, por lo que a menudo es posible usar NULL sin incluir explícitamente <cstddef>, pero depender de que siempre ha sido no portátil. Está bien usar NULL siempre que incluya su encabezado, aunque solo se usa 0 en idiomático C++.

+1

Gracias por los detalles. En todas partes, aunque he trabajado, parece preferir usar NULL en 0. – AlastairG

+1

Hay cosas que * han * cambiado desde '98. Por ejemplo: 'auto' ya no es un especificador de clase de almacenamiento; en C++ 0x, es equivalente a 'var' en otros idiomas, haciendo deducción de tipo automático. – greyfade

+0

grayfade, C++ 0x no está terminado y aún no es el predeterminado para los compiladores, por lo que no creo que sea correcto decir que el idioma * ha * cambiado. Sin embargo * cambiará *. – Wyzard

0

Si ha utilizado versiones anteriores de varias bibliotecas, como Boost, existen algunos problemas.

0

Muy similar a la respuesta de sharptooth, hay bits de código C y C++ anterior que necesitarán/ZC: forScope- set (es decir, no fuerce la conformidad en el alcance del bucle). p.ej.

int myfunc(int x, int y, int z) 
{ 
    int j; 

    for (int i=0; i <= 10; i++) 
    { 
    if (f(i) == 0) 
     break; 
    } 
    j = i; 
    for (i=0; i <= 10; i++) 
    { 
    if (g(i) == 0) 
     break; 
    } 
    if (i > j) 
    return j; 
    return i; 
} 

Este tipo de cosas es bastante común en el código mucho más antigua, donde bytes cuestan dinero y reutilización variable fue lugar común.

+0

¿Eh? Eso debería compilarse sin interruptores, es un comportamiento estándar. (¡En particular, no ha puesto nada en el alcance!) –

+0

Mi mal. Editado, la declaración movida si yo –

4

Esto depende de lo que esté comparando.

  • Visual Studio 2010 implementa parcialmente el próximo draft C++ 0x (versiones recientes de GCC también implementar un subconjunto de este proyecto, que se espera que sea estandarizado próximo año)
  • C++ 98/C + 03 fue la primera versión estandarizada de C++, y sigue siendo la oficial (como C++ 0x es todavía sólo un proyecto)
  • y, por supuesto, están los dialectos de delante de la lengua fue estandarizada

C++ 0x es prácticamente compatible con C++ 03/98. Puede haber un par de casos oscuros en las esquinas que han cambiado, pero es poco probable que los encuentres. Sin embargo, se produjeron muchos cambios cuando el idioma era primero estandarizado, lo que significa que C++ 98 no es del todo (pero casi) compatible con C++ pre-estándar.

Pero lo más probable es que no se trate de la compatibilidad con versiones anteriores de C++, sino simplemente de que los compiladores se han vuelto más estrictos. Se han vuelto mucho mejores al seguir el estándar y ya no permiten muchos trucos no estándar que eran comunes antes. Lo más probable es que su código anterior fuera nunca C++ válido, pero funcionó porque los compiladores solían desviarse del estándar.

0

Un poco al azar, pero la palabra clave export se está eliminando del estándar. Entonces, el código previamente compatible con las normas export usado ahora sería ilegal. Por supuesto, muy pocos compiladores incluso comenzaron a implementar esa palabra clave.

Cuestiones relacionadas