Exemplo de comportamento indefinido mais curto em C ++ [fechado]


8

Qual é o código C ++ mais curto e bem formado que exibe comportamento indefinido?


1
O que você quer dizer com "executável"? Se tiver UB, não há garantia de que possa ser executado.
R. Martinho Fernandes

@ R.MartinhoFernandes bem, quero dizer que começa.
Luchian Grigore 22/08/2012

@LuchianGrigore que é muito dependente do compilador (versão).
rubenvb

1
Defina "exposições". Precisa mostrar alguma coisa? Ou é suficiente que o estado da memória interna seja indefinido em algum momento durante o programa?
Sr. Lister

Respostas:


12
int main(){main;}

3.6.1 Função principal [basic.start.main]

3 - [...] A função main não deve ser usada dentro de um programa.

Edit: isso é diagnosticável, então não UB.


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

1.10 Execuções multithread e corridas de dados [intro.multithread]

24 - A implementação pode assumir que qualquer encadeamento acabará executando um dos seguintes procedimentos: - finalize, - faça uma chamada para uma função de E / S da biblioteca, - acesse ou modifique um objeto volátil, ou - execute uma operação de sincronização ou operação atômica .


int main(){int i=i;}

4.1 Conversão de valor em valor [conv.lval]

1 - [...] Se o objeto ao qual o glvalue se refere não for [...] inicializado, um programa que necessite dessa conversão terá um comportamento indefinido.


//^L.

Aqui ^Lestá o caractere de feed de formulário, que faz parte do conjunto de caracteres básico. 4 caracteres (uma nova linha não é necessária por 2.2: 2). O comportamento indefinido é por

2.8 Comentários [lex.comment]

1 - Se houver um feed de formulário ou um caractere de tabulação vertical no comentário [a- //style], somente caracteres de espaço em branco aparecerão entre ele e a nova linha que termina o comentário; nenhum diagnóstico é necessário.


o segundo não está indefinido. Ele pode otimizar o loop for sem problemas. Esse não é um comportamento indefinido.
rubenvb

3
@rubenvb stackoverflow.com/questions/3592557/… - sempre que o padrão diz "o compilador pode assumir P", está implícito que um programa que possui a propriedade not-P possui semântica indefinida .
ecatmur

no entanto, o compilador também pode não assumir efeitos colaterais ao excluir os construtores de cópia.
rubenvb

@rubenvb porque esse caso específico é explicitamente mencionado.
R. Martinho Fernandes

1
@BogdanAlexandru, seu projeto incorporado possui um comportamento indefinido. Isso significa que pode funcionar como o esperado agora, mas quando você atualiza seu compilador, ele se comporta de maneira diferente.
ecatmur

5
\u\
0000

Possui oito caracteres e comportamento indefinido, de acordo com o §2.2 / 1.

Cada instância de um caractere de barra invertida ( \) imediatamente seguida por um caractere de nova linha é excluída, emendando as linhas de origem físicas para formar linhas de origem lógicas. Somente a última barra invertida em qualquer linha de origem física será elegível para fazer parte dessa emenda. Se, como resultado, uma sequência de caracteres que corresponde à sintaxe de um nome universal de caractere for produzida, o comportamento será indefinido.


este não é o "programa". Um programa tem um main.
rubenvb

@rubenvb Experimente no Hell ++. Tem um comportamento indefinido, portanto pode ser um programa sem a main. É difícil impor regras quando você solicita um programa que não tem nenhuma regra a seguir (é isso que UB significa!).
R. Martinho Fernandes

3
Com base na redação da pergunta, acho que isso se qualifica - ele pede apenas o menor "código" que exibe UB. Com base no "executável" no comentário, acho que a intenção, no entanto, era o programa mais curto , o que excluiria seu código, porque de acordo com o §3.6.1 / 1: "Um programa deve conter uma função global chamada main, qual é o início designado do programa ". Como tal, sem main, o que você tem é mal formado.
Jerry Coffin

1
@JerryCoffin Ele está usando um ambiente independente em que o principal não é necessário. Você convenientemente deixou de fora o restante do §3.6.1 / 1, que diz "É definido pela implementação se um programa em um ambiente independente é necessário para definir uma função principal". Este é um programa válido ("válido", pois é um "programa" de acordo com o seu argumento).
David

Dang, só vim aqui para trazer esse. +1
Columbo

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

§16.2 / 4:

Uma diretiva de pré-processamento do formulário

             #include  nova linha de tokens pp

(que não corresponde a uma das duas formas anteriores) é permitido. [..] Se a diretiva resultante após todas as substituições não corresponder a uma das duas formas anteriores, o comportamento será indefinido.


Ele não será analisado da mesma forma se você remover o espaço antes do ponto?
usar o seguinte código

@feersum Sim. Isso não altera a idéia, razão pela qual a evitei melhorar a legibilidade, mas acho que serve ao ponto da pergunta para ilustrar que o espaço pode ser omitido. Obrigado!
Columbo

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

Explicação:

C ++ 98 e C ++ 11 §5.8 / 1 afirmam que

O comportamento é indefinido se o operando direito for negativo ou maior ou igual ao comprimento em bits do operando esquerdo promovido.


3
em um sistema de 32 bits, o comprimento em bits intnormalmente não é de 32? mudando o RHS da mudança para -1o mesmo número de caracteres e não dependerá de tamanhos inteiros
ardnew

1

Se alguém acreditar na wikipedia, aqui estão alguns:

Diz-se que modificar cadeias causa um comportamento indefinido. Sempre funcionou para mim.

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

Uma função não nula sem retorno causa valores de retorno indefinidos.

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

A divisão (de int?) Por zero é supostamente indefinida. Tudo o que sei é que ele trava.

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

Esses não são trechos de código legais. Principal deve ser definido como int main(){}no mínimo.
rubenvb

Porra, eu tinha certeza que a pergunta era sobre C. Desculpe por isso.
shiona

1
@shiona o segundo parâmetro char **não deve ser char *. Você está apenas modificando parte de um valor de ponteiro. De fato, argvé garantido que seja modificável com segurança.
oldrinb

O padrão permite que os literais de seqüência de caracteres sejam somente leitura, muitas implementações fazem isso. É correto char *argv[]não ter constqualificadores. Você pode falhar, escrevendo em um literal string comint main(){char *v="";*v=1;}
Peter Cordes

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.