Muestra de comportamiento indefinido más corta en C ++ [cerrado]


8

¿Cuál es el código C ++ más corto y bien formado que exhibe un comportamiento indefinido?


1
¿Qué quieres decir con "runnable"? Si tiene UB, no hay garantía de que pueda ejecutarse.
R. Martinho Fernandes

@ R.MartinhoFernandes bueno, quiero decir que comienza.
Luchian Grigore

@LuchianGrigore que depende mucho del compilador (versión).
rubenvb

1
Definir "exposiciones". ¿Necesita mostrar algo? ¿O es suficiente que el estado de la memoria interna no esté definido en algún momento durante el programa?
Sr. Lister el

Respuestas:


12
int main(){main;}

3.6.1 Función principal [basic.start.main]

3 - [...] La función main no se utilizará dentro de un programa.

Editar: esto es diagnosticable, así que no UB.


int main(){for(;;);}

1.10 Ejecuciones multiproceso y carreras de datos [intro.multithread]

24 - La implementación puede suponer que cualquier subproceso finalmente realizará una de las siguientes acciones: - finalizar, - realizar una llamada a una función de E / S de la biblioteca, - acceder o modificar un objeto volátil, o - realizar una operación de sincronización o una operación atómica .


int main(){int i=i;}

4.1 Conversión Lvalue-to-rvalue [conv.lval]

1 - [...] Si el objeto al que se refiere el valor gl no está [...] inicializado, un programa que necesita esta conversión tiene un comportamiento indefinido.


//^L.

Aquí ^Lestá el carácter de fuente de formulario, que es parte del conjunto de caracteres básico. 4 caracteres (no se requiere una nueva línea por 2.2: 2). El comportamiento indefinido es por

2.8 Comentarios [lex.comment]

1 - Si hay un formulario de alimentación o un carácter de tabulación vertical en el //comentario [a- style], solo aparecerán caracteres de espacio en blanco entre este y la nueva línea que termina el comentario; No se requiere diagnóstico.


el segundo no está indefinido. Puede optimizar el bucle for sin problemas. Ese no es un comportamiento indefinido.
rubenvb

3
@rubenvb stackoverflow.com/questions/3592557/… - cada vez que el estándar dice "el compilador puede asumir P", se da a entender que un programa que tiene la propiedad no-P tiene una semántica indefinida .
ecatmur

sin embargo, el compilador también puede asumir que no tiene efectos secundarios al eludir constructores de copia.
rubenvb

@rubenvb porque ese caso particular se menciona explícitamente .
R. Martinho Fernandes

1
@BogdanAlexandru su proyecto incrustado tiene un comportamiento indefinido. Eso significa que podría funcionar como espera ahora, pero cuando actualice su compilador se comportará de manera diferente.
ecatmur

5
\u\
0000

Tiene ocho caracteres y tiene un comportamiento indefinido, según §2.2 / 1.

Cada instancia de un carácter de barra diagonal inversa ( \) seguida inmediatamente por un carácter de nueva línea se elimina, uniendo líneas de origen físicas para formar líneas de origen lógicas. Solo la última barra diagonal inversa en cualquier línea de fuente física será elegible para formar parte de dicho empalme. Si, como resultado, se produce una secuencia de caracteres que coincide con la sintaxis de un nombre de carácter universal, el comportamiento es indefinido.


esto no es & "programa". Un programa tiene a main.
rubenvb

@rubenvb Pruébalo en Hell ++. Tiene un comportamiento indefinido, por lo que puede ser un programa sin un main. Es difícil hacer cumplir las reglas cuando solicitas un programa que no tiene reglas que seguir (¡eso es lo que significa UB!).
R. Martinho Fernandes

3
Según la redacción de la pregunta, creo que esto califica: solo pide el "código" más corto que muestra UB. Basado en el "ejecutable" en el comentario, creo que la intención, sin embargo, fue el programa más corto , que descartaría su código, porque de acuerdo con §3.6.1 / 1: "Un programa contendrá una función global llamada main, cual es el inicio designado del programa ". Como tal, sin mainlo que tienes está mal formado.
Jerry Coffin

1
@JerryCoffin Él está utilizando un entorno independiente donde no se requiere main. Convenientemente omitió el resto de §3.6.1 / 1 que dice "Está definido por la implementación si un programa en un entorno independiente es necesario para definir una función principal". Este es un programa válido ("válido" ya que es un "programa" según su argumento).
David

Dang, acabo de venir aquí para traer eso. +1
Columbo

2
#include. /*Imagine a new-line right after the dot*/

§16.2 / 4:

Una directiva de preprocesamiento del formulario

             #include  pp-tokens nueva línea

(que no coincide con una de las dos formas anteriores) está permitido. [..] Si la directiva resultante después de todos los reemplazos no coincide con una de las dos formas anteriores, el comportamiento es indefinido.


¿No analizará lo mismo si elimina el espacio antes del punto?
feersum

@feersum Sí. Eso no altera la idea, por eso lo evité para mejorar la legibilidad, pero supongo que sirve el punto de la pregunta para ilustrar que el espacio puede omitirse. ¡Gracias!
Columbo

2
int main(){int i=1>>-1;}

Explicación:

C ++ 98 y C ++ 11 §5.8 / 1 afirman que

El comportamiento es indefinido si el operando derecho es negativo, o mayor o igual que la longitud en bits del operando izquierdo promovido.


3
en un sistema de 32 bits, ¿no es la longitud en bits inttípicamente de 32? cambiar el RHS del cambio a -1es el mismo número de caracteres y no dependerá de los tamaños de los números enteros
nuevo el

1

Si uno debe creer en Wikipedia, aquí hay algunos:

Se dice que modificar cadenas provoca un comportamiento indefinido. Siempre me ha funcionado.

int main(int c,char*v){v[0]='.';}

Una función no nula sin retorno produce valores de retorno indefinidos.

int a(){}
int main(){return a();}

La división (de int?) Por cero está supuestamente indefinida. Todo lo que sé es que se bloquea.

int main(int c){c/0;}

Estos no son fragmentos de código legal. Principal debe definirse como int main(){}mínimo.
rubenvb

Maldición, estaba seguro de que la pregunta era sobre C. Lo siento.
shiona

1
@shiona el segundo parámetro debe ser char **no char *. Simplemente está modificando parte de un valor de puntero. De hecho, argvse garantiza que se puede modificar de forma segura.
oldrinb

El estándar permite que los literales de cadena sean de solo lectura, por lo que muchas implementaciones lo hacen. Es correcto char *argv[]no tener ningún constcalificador. Podría bloquearse escribiendo en un literal de cadena conint main(){char *v="";*v=1;}
Peter Cordes

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.