2009-11-16 33 views
15

Estoy acostumbrado al estilo antiguo C y recientemente comencé a explorar las características del c99. Solo tengo una pregunta: ¿mi programa se compilará correctamente si uso c99 en mi programa, la bandera c99 con gcc y lo conecto con las bibliotecas anteriores de c99?¿C99 es compatible con C89?

Por lo tanto, debería atenerse a C89 de edad o evolucionar?

+0

gracias a todas las respuestas. veo más ventajas que inconvenientes aquí, así que empacar cosas y pasar a c99 ahora: p – kar

Respuesta

9

creo que son compatibles en este sentido. Eso es mientras las cosas sobre las que compilas no pisen ninguno de los nuevos objetos. Por ejemplo, si el código anterior contiene , entonces tiene problemas. Como un dinosaurio similar, estoy abrazando lentamente el maravilloso mundo nuevo de C99. Después de todo, solo ha estado al acecho por alrededor de 10 años;)

+8

En realidad, siempre y cuando no incluya '', puede usar el identificador 'bool' en el código C99. C99 define las palabras clave '_Bool',' _True' y '_False' como parte del lenguaje, y el encabezado' 'aliases a' bool', 'true' y' false'. –

+1

Técnicamente, el tipo de retorno implícito 'int' está permitido en C89 pero no en C99, pero si su código todavía los usa, entonces usted tiene problemas mucho más grandes y debería cambiar a C99 solo para limpiarlos. (Tenga en cuenta que puede haber algunos otros problemas C89/C99 en esta línea, pero todos caen dentro de la misma categoría más o menos). –

+0

AFAIK, verdadero y falso están definidos a 1 y 0. _Verdadero y _Falso no existen. – marcus

1

Está diseñado para ser compatible con versiones anteriores. Se formalizan extensiones que muchos proveedores ya han implementado. Es posible, tal vez incluso probable, que un programa bien escrito no tenga problemas al compilar con C99.

En mi experiencia, la recompilación de algunos módulos y no otros para ahorrar tiempo ... desperdicia mucho tiempo. Por lo general, hay algunos detalles que se pasan por alto fácilmente y que necesitan el nuevo compilador para que todo sea compatible.

2

Respetuosamente: Pruébalo y descúbrelo. :-)

Sin embargo, tenga en cuenta que incluso si necesita corregir algunas diferencias de compilación de minior, es probable que valga la pena moverse hacia arriba.

2

Si no infringe las características explícitas de C99, un código c90 funcionará correctamente con otras bibliotecas c99 anteriores.

Pero hay algunos dos bibliotecas basadas en C89 como ,, que sin duda no va a funcionar.

C99 es mucho más flexible, así que no dude migrar :-)

2

Las convenciones de llamada entre bibliotecas de C no ha cambiado en mucho tiempo, y de hecho, no estoy seguro de que lo ha logrado.

Los sistemas operativos en este punto se basan en gran medida en las convenciones de llamadas C ya que las API C tienden a ser el pegamento entre las piezas del sistema operativo.

Así que, básicamente, la respuesta es "Sí, los binarios serán compatibles con versiones anteriores. No, naturalmente, el código que utiliza las características C99 no puede compilarse más adelante con un compilador que no sea C99".

7

Debe evolucionar. Gracias por escuchar :-)

En realidad, voy a ampliar en eso.

tienes razón en que el C99 ha sido de alrededor durante bastante tiempo. Usted debería (en mi opinión) usar ese estándar para cualquier cosa que no sea código heredado (donde solo corrige errores en lugar de agregar nuevas características). Probablemente no valga la pena por el código heredado, pero debería (como con todas las decisiones comerciales) hacer su propio análisis de costo/beneficio.

Ya me estoy asegurando de que mi nuevo código sea compatible con C1x, aunque no estoy usando ninguna de las características nuevas, intento asegurarme de que no se rompa.

En cuanto a qué código tener en cuenta, los autores de las normas tienen compatibilidad con versiones anteriores muy en serio.Su trabajo no era diseñar un nuevo idioma, sino codificar las prácticas existentes.

La fase en la que se encuentran en este momento les permite tener más libertad para actualizar el idioma, pero aún siguen el juramento hipocrático en términos de su producción: "antes que nada, no hagan daño".

Generalmente, si su código se rompe con un nuevo estándar, el compilador se ve obligado a informarle. Entonces, simplemente compilar tu base de código será un excelente comienzo. Sin embargo, si lee el C99 rationale document, verá aparecer la frase "cambio silencioso": esto es lo que debe tener en cuenta.

Estos son cambios de comportamiento en el compilador sobre los que no es necesario que se informe y pueden ser fuente de mucha angustia y crujir de dientes si la aplicación comienza a actuar de forma extraña. No se preocupe por el "cambio silencioso en c89" bits - si fueran un problema, usted ya habría sido mordido por ellos.

Ese documento, por cierto, es una lectura excelente para entender por qué el estándar real dice lo que dice.

+0

¿Tiene un indicador de qué cosas nuevas vienen en C1x? Parece que las TR 'de función segura' no se están incorporando (al menos no parecen estar en el borrador de marzo de 2009). Prefiero no tener que leer todo el borrador para tratar de descubrir las cosas nuevas. –

+0

Estoy usando n1362 (borrador de marzo). Las cosas se pueden retirar hasta el momento en que se aprueba oficialmente el estándar (aunque, por supuesto, es menos probable a medida que se acerca la votación). A pesar de que creo que las funciones "seguras" son una muleta para las personas que no tienen codificación empresarial en C en primer lugar :-), sigo actuando como si estuvieran allí, ya que WG14 todavía está trabajando en ellos en mayo de 2009 (aunque noto que ahora los llaman las "interfaces de comprobación de límites" más aptas), nunca fueron * seguros *. No los estoy usando, simplemente asegurándome de que el código * my * no esté roto por ellos. – paxdiablo

+0

En realidad, no odio tanto las funciones limitadas, ya que reducen el esfuerzo. Solo odiaba el hecho de que se llamaran seguros. Solo son seguros si los usa correctamente y eso es cierto para las funciones * all * C. – paxdiablo

1

Algunas características C89 no son válidos C99

Podría decirse que existen esas características sólo por razones históricas, y no debe utilizarse en el código C89 moderna, pero existen.

The C99 N1256 standard draft prólogo El párrafo 5 compara C99 con revisiones anteriores, y es un buen lugar para comenzar a buscar esas incompatibilidades, aunque con mucho más extensiones que restricciones.

implícito retorno int y los tipos de variables

mencionadas por Lutz en un comentario, por ejemplo los siguientes son C89 válida:

static i; 
f() { return 1; } 

pero no C99, en el que usted tiene que escribir:

static int i; 
int f() { return 1; } 

Esto también impide llamar a las funciones sin prototipos de C99: Are prototypes required for all functions in C89, C90 or C99?

n1256 dice:

eliminar implícito int

Retorno sin expresión para la función no nula

Válido C89, C99 no válido:

int f() { return; } 

Creo que en C89 devuelve un valor definido por la implementación.n1256 dice:

retorno sin expresión no permitida en función que devuelve un valor

La división entera con el operando negativo

  • C89: rondas a una dirección definida por la implementación
  • C99: rondas a 0

Así que si su compilador se redondeó a -inf, y usted confió en ese comportamiento definido de implementación, su compilador ahora está obligado a romper su código en C99.

https://stackoverflow.com/a/3604984/895245

n1256 dice:

número entero fiable división

compatibilidad con Windows

Una preocupación importante práctica es ser capaz de compilar en Windows, ya que Microsoft does not intend to implement C99 fully too soon .

Esto es por ejemplo por qué libgit2 limits allowed C99 features.

+0

Una diferencia más significativa es que en C89, la definición de operadores de dirección e indirección implicaba que si 'v' es un valor l de tipo' T', entonces después de 'T * p = & v', los lvalues' v' y '* p' será equivalente dentro de sus livetimes a menos que' p' se sobrescriba, y ese principio se aplica incluso si 'v' era un miembro de la unión. Escribir un miembro del sindicato como un tipo y leer como otro se definiría en algunos casos (por ejemplo, la Garantía de secuencia inicial común) y en otros casos sería Implementación definida, lo que significa que las implementaciones tenían que especificar si aliasing entre punteros (en lugar de entre ... – supercat

+0

... un puntero y un lvalue directamente accedido) harían algo distinto a los datos reinterpretados por byte. C99 cambia esas reglas de maneras que hacen esencialmente imposible adaptar el código que tendría un comportamiento bien definido en la mayoría de los compiladores C89, y podría probar en tiempo de compilación las características inusuales que lo romperían. – supercat

+0

@supercat gracias por la explicación. Agregue un ejemplo de código mínimo con una explicación de diferencia de comportamiento de un trazador de líneas C89 vs C99 en alguna parte :-) –

1

Hay algunas partes del Estándar C89 que están ambiguamente escritas, y dependiendo de cómo se interprete la regla sobre los tipos de punteros y los objetos a los que están accediendo, el Estándar se puede ver como una descripción de dos muy diferentes idiomas, uno de los cuales es semánticamente mucho más poderoso y consecuentemente utilizable en una gama más amplia de campos, y uno de los cuales permite más oportunidades para la optimización basada en el compilador. El estándar C99 "aclaró" la regla para dejar en claro que no hace ningún esfuerzo para exigir compatibilidad con el idioma original, a pesar de que fue ampliamente favorecido en muchos campos; también trata como indefinido algunas cosas que se definieron en C89, pero solo porque las reglas C89 no se escribieron con la precisión suficiente para prohibirlas (por ejemplo, el uso de memcpy para el tipo de juego de palabras cuando el destino tiene duración de montón).

C99 puede ser compatible con el lenguaje que sus autores pensaban que fue descrito por C89, pero no es compatible con el lenguaje procesado por la mayoría de los compiladores C89 a lo largo de la década de 1990.