Udemy

Lenguaje de programación C- standard

Lenguaje de programación C - standard


¿Qué hacer cuando un programa C produce resultados diferentes en dos compiladores diferentes? 
Por ejemplo, considere el siguiente programa simple de 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.

#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 esas 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 último estándar C es ISO / IEC 9899: 2011 , también conocido como C11 ya que el borrador final se publicó en 2011. Antes de C11, existía C99 . El borrador final del C11 está disponible aquí . Vea esto para ver el historial completo de los estándares C.
¿Podemos conocer el comportamiento de todos los programas del estándar C? 
El estándar C deja el comportamiento de muchas construcciones C como indefinidas y algunas como no especificadas 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 las evaluaciones de subexpresiones no está especificado. Esto libera específicamente al compilador para hacer 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
Por lo tanto, el tipo de retorno nulo 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 enumera bajo 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 es indefinido o no especificado en el estándar? 
Como programador, nunca es una buena idea usar construcciones de programación cuyo comportamiento sea indefinido o no especificado, tales programas siempre deben desalentarse. La salida de dichos programas puede cambiar con el compilador y / o la máquina.

No hay comentarios.