Muchas veces se habla de comportamiento indefinido, no especificado y definido por la implementacion en c
. Sin embargo, ¿qué diferencia existe entre estos conceptos?
- 347
- 1
- 7
-
Hola Maur. ¿Has investigado algo? ¿Qué no te queda claro? Esta pregunta tiene un trasfondo puramente teorico o no sabes cómo aplicarlo a un problema práctico? Mira [ask] y [help/on-topic] para más info en como mejorar la pregunta. Un saludo – lois6b May 14 '18 at 09:57
-
@lois6b la diferencia entre los dos conceptos – Maur May 14 '18 at 10:03
-
1Hubo una charla sobre esta temática en el evento using std::cpp en la Carlos III de Madrid, puedes ver la charla completa [aquí](https://usingstdcpp.org/using-stdcpp-2014/programa/unspecified-vs-undefined/) (ojo: la charla es sobre [tag:C++], no sobre [tag:C]). – PaperBirdMaster May 14 '18 at 10:31
-
no añadas contenido a una respuesta alegremente... en este caso no tiene sentido que añada ese apartado cuando no se menciona en la pregunta. Si aun así te gustaría que constase, plantéate añadir tu propia respuesta... o modifica la pregunta – eferion May 14 '18 at 11:35
-
@eferion entendido, pregunta editada – Maur May 14 '18 at 11:36
-
También te aviso que este tipo de cambios sustanciales pueden invalidar las respuestas que ya has recibido... este tipo de ediciones tienen que ser muy puntuales ya que no es que a tu pregunta le faltase algo para poder responderse sino que directamente te ha parecido bien añadir nuevos requisitos a la misma de forma unilateral – eferion May 14 '18 at 11:39
-
@eferion entonces que hago la pongo como estaba antes o la dejo asi, que es lo que te parece mas correcto? – Maur May 14 '18 at 11:43
-
No, puedes dejarlo así, es más un aviso para futuras ocasiones. Este tipo de cambios invalida las respuestas anteriores y es conveniente evitar este tipo de prácticas. – eferion May 14 '18 at 11:44
-
@eferion añado ahora lo de comportamiento definido por la implementacion a una respuesta (responde a tu pregunta) o lo añades tu a tu respuesta? – Maur May 14 '18 at 11:57
-
[Continuemos el debate en el chat](https://chat.stackexchange.com/rooms/77463/discussion-between-eferion-and-maur). – eferion May 14 '18 at 13:37
2 Answers
Comportamiento indefinido
Aparece cuando el comportamiento de un algoritmo tiene errores que, si bien generan código válido, el resultado final será dependiente de factores tan peregrinos como la plataforma en la que se ejecute o el compilador elegido para generar el programa.
char* cadena = "Hola a todos";
cadena[0] = 'h';
El ejemplo anterior provoca un comportamiento no definido porque es probable que la cadena se almacene en una región de solo lectura. En ese caso el intento por modificarla provocará un error en tiempo de ejecución. En cambio, si la cadena se almacena en una región de la memoria que admita escrituras el código funcionará sin problemas.
Otros ejemplos de comportamiento indefinido:
free sobre memoria no reservada
int* ptr;
free(ptr);
llamar a free dos veces seguidas (particularidad del caso anterior)
int* ptr = (int*)malloc(sizeof(int));
free(ptr);
free(ptr);
División entre 0
int a = 10;
int b = a/0;
Omisión de return
int func(int a, b)
{
int c = a + b;
}
En este caso habrá compiladores que pueden llegar a mostrarte una advertencia pero no conviene acostumbrarse a depender de las mismas ya que no es algo que vaya a estar garantizado (el que aparezcan).
Comportamiento no especificado
El comportamiento no especificado lo encontramos en aquellas situaciones en las que el estándar da cierta libertad al compilador a la hora de elegir el orden en el que se ejecutan las instrucciones.
void func(int a, int b)
{
printf("%d %d",a,b);
}
int i=0;
func(i++,i++);
El ejemplo anterior puede imprimir varios resultados:
0 0
0 1
1 0
Y todo depende del orden en el que se evaluen los incrementos... lo que depende del compilador.
-
intentar desreferenciar un puntero nulo o hacer dos free para un mismo malloc seria por ejemplo comportamiento indefinido no? – Maur May 14 '18 at 10:09
-
-
el orden de evaluacion de los argumentos de una funcion y las llamadas a funciones seria no especificado? – Maur May 14 '18 at 10:19
-
@Maur sí. El estándar define lo que se denominan *puntos de secuencia* que son los que delimitan la libertad del compilador para evaluar las variables y ordenarlas según sus prioridades. Pero entre dos puntos de secuencia el compilador es libre para organizar las instrucciones a su gusto con pocas limitaciones – eferion May 14 '18 at 10:23
-
entonces los puntos de secuencia seria lo que en c++ es llamado "comportamiento definido por la implementación" ? – Maur May 14 '18 at 10:52
En octubre de 2014, en la Universidad Carlos III (Madrid) tuvo lugar un evento de charlas técnicas sobre C++, uno de los ponentes (Juan Soulié, desarrollador de la web cplusplus.com) dio una charla precisamente sobre el tema que preguntas: Unspecified vs Undefined Behavior1.
En resumen, indicó que el comportamiento no especificado es un código correcto cuyo efecto no está especificado en estándar, su comportamiento depende de cómo lo implemente el compilador y a veces, el estándar lo limita o esboza. Hay que tener en cuenta que puede ser consistente, o no serlo.
Por otro lado, el comportamiento indefinido es un código sintácticamente correcto cuyo efecto no está especificado en el estándar y su efecto puede ser cualquiera2.
Adicionalmente, la charla introduce el concepto de comportamiento definido por la implementación, que es un código correcto cuyo efecto no está especificado en estándar, su comportamiento depende de cómo lo implemente el compilador y a veces, el estándar lo limita o esboza y a diferencia del comportamiento no especificado, debe estar documentado en el estándar y ser consistente.
- Aunque el título esté en inglés, toda la charla, las diapositivas y las bromas son en perfecto Español.
- Algunos programadores afirman que entre los efectos resultantes de ejecutar un código con comportamiento no especificado, el compilador podría decidir expulsar demonios a través de tus fosas nasales.
- 44,474
- 6
- 44
- 82