Estándar de lenguaje de programación C

 

La idea de este artículo es introducir el estándar C. 

¿Qué hacer cuando un programa en C produce resultados diferentes en dos compiladores diferentes?  
Por ejemplo, considere el siguiente programa en C simple. 

C

void main() {  }

El programa anterior falla en gcc ya que el tipo de retorno de main es nulo, pero se compila en Turbo C. ¿Cómo decidimos si es un programa C legítimo o no? 

 

Considere el siguiente programa como otro ejemplo. Produce diferentes resultados en diferentes compiladores. 

C

#include<stdio.h>
int main()
{
    int i = 1;
    printf("%d %d %d\n", ++i, i++, i);
    return 0;
}
2 1 3 - using g++ 4.2.1 on Linux.i686
1 2 3 - using SunStudio C++ 5.9 on Linux.i686
2 1 3 - using g++ 4.2.1 on SunOS.x86pc
1 2 3 - using SunStudio C++ 5.9 on SunOS.x86pc
1 2 3 - using g++ 4.2.1 on SunOS.sun4u
1 2 3 - using SunStudio C++ 5.9 on SunOS.sun4u

Fuente: Stackoverflow
¿Qué compilador es el correcto?
La respuesta a todas estas preguntas es el estándar C. En todos estos casos, necesitamos ver qué dice el estándar C sobre dichos programas.

¿Qué es el estándar C?  
El estándar C más reciente es ISO/IEC 9899:2011 , también conocido como C11 , ya que el borrador final se publicó en 2011. Antes del C11, existía el C99 . El borrador final del C11 está disponible aquí . Consulte esto para obtener una historia completa de los estándares C.

¿Podemos conocer el comportamiento de todos los programas del estándar C?  
El estándar C deja parte del comportamiento de muchas construcciones de C sin definir y algunas sin especificar para simplificar la especificación y permitir cierta flexibilidad en la implementación. Por ejemplo, en C, el uso de cualquier variable automática antes de que se haya inicializado produce un comportamiento indefinido y el orden de evaluación de las subexpresiones no está especificado. Esto libera específicamente al compilador para que haga lo que sea más fácil o más eficiente, en caso de que se envíe dicho programa.

Entonces, ¿cuál es la conclusión sobre los dos ejemplos anteriores?  
Consideremos el primer ejemplo que es «void main() {}», el estándar dice lo siguiente sobre el prototipo de main().

The function called at program startup is named main. The implementation 
declares no prototype for this function. It shall be defined with a return 
type of int and with no parameters:
       int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names 
may be used, as they are local to the function in which they are declared):
       int main(int argc, char *argv[]) { /* ... */ }
or equivalent;10) or in some other implementation-defined manner.

Entonces, el tipo de retorno void no sigue el estándar, y es algo permitido por ciertos compiladores.

Hablemos del segundo ejemplo. Tenga en cuenta que la siguiente declaración en el estándar C se incluye en el comportamiento no especificado.  

The order in which the function designator, arguments, and 
subexpressions within the arguments are evaluated in a function 
call (6.5.2.2). 

¿Qué hacer con los programas cuyo comportamiento no está definido o especificado en el estándar?  
Como programador, nunca es una buena idea usar construcciones de programación cuyo comportamiento no esté definido o especificado, dichos programas siempre deben desaconsejarse. La salida de tales programas puede cambiar con el compilador y/o la máquina.
Este artículo es una contribución de Abhay Rathi . Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *