Escreva um programa curto, que geraria a maior mensagem de erro possível, em um compilador padrão C ++ ( gcc
, cl.exe
, icc
ou clang
).
A pontuação de cada entrada é o número de caracteres na mensagem de erro mais longa que o compilador emitiu. Os tipos incluídos no seu código-fonte e citados pelo compilador são contados como um único caractere.
Traindo
Você sempre pode redefinir um modelo em modelo com nomes longos, mas espero algo criativo. Tentei impedir um pouco disso pela última regra, mas é claro que as regras podem ser melhores, e ficarei feliz em obter melhorias.
code-challenge
c++
error-message
Elazar Leibovich
fonte
fonte
Error.message.length / code.length
.Respostas:
É fácil decifrar as mensagens de erro do modelo. Considere isto:
Compilar com
gcc -c error.cpp
(4.6.3) produzirá 15786 bytes de saída, com uma linha mais longa de 330 caracteres.Edit 29-04-2016: o gcc 5.3.0 ficou um pouco melhor: apenas 9300 bytes, a linha mais longa tem 361 caracteres ...
Edite 2019-04-04: gcc 6.5.0: 11237 bytes, mas fornece algumas dicas sobre o erro, como nessas linhas:
fonte
19 caracteres
Crie um arquivo
a.cpp
com este conteúdo:Compilar como:
e receba incríveis mensagens de erro de 21300 linhas :
...
... 21280 linhas de erro ...
...
fonte
#include __FILE__
um nome de arquivo muito longo ..?clang++ -ferrorlimit=1000 a.cpp
. A linha mais longa tem 466 caracteres.98 caracteres (necessários):
Produz a seguinte saída de erro no GCC (4.4.5):
Estatisticas:
Ungolfed (produz saída mais longa):
Descobri isso quando queria ver se o C ++ suporta recursão polimórfica (e, como você pode ver claramente, não). Aqui está um exemplo trivial de recursão polimórfica em Haskell:
Aqui, isso requer Haskell a agir como ele instancia
Show x
,Show [x]
,Show [[x]]
,Show [[[x]]]
, ad infinitum. Haskell faz isso transformando(Show x) =>
- se em um parâmetro implícito para a funçãof
adicionada pelo compilador, algo como isto:O C ++ faz isso literalmente tentando construir essas instâncias até que a profundidade da instanciação do modelo seja excedida.
fonte
cl
não gosta implícitoint
no modo C ++), gera 14.380.923 bytes de saída de erro após 4½ minutos de tempo de CPU e um pico de cerca de 100 MiB de uso de memória.Com base na proporção do comprimento da mensagem / comprimento do código, esta pode ser a melhor solução:
Mensagem (81):
81/0 = Inf
fonte
279 caracteres
Com o gcc 4.2.1, gera o erro
error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘foofoo....foofoo’
com 2 ^ 21 cópias defoo
. 6.291.558 bytes no total. É o maior identificador possível, substituindofoo
porfood
gera um ICE.fonte
#define A(s) s##s##s##s #define B(s) A(s) #define C(s) B(B(B(s))) #define D(s) C(C(C(s))) D(foo)
. Isso gera uma mensagem de erro com muito menos código e cresce muito mais rápido com o aumento do padrão em qualquer dimensão, pois estamos implementando essencialmente a função Ackermann.Semelhante ao VJo:
a.cpp:
g ++ a.cpp
produz muita saída (pelo menos 2 gigabytes antes de eu a matar)
fonte
O código a seguir é baseado em um erro real que encontrei uma vez.
(usando gcc)
Recursão de modelo bastante óbvia, mas desde que eu usei
ftemplate-depth=100000
essa execução, isso não produz um erro. A fonte real das mensagens de erro vemchar baz[i];
, o que produz um erro quandoi
cai para -1.Após cerca de meia hora, estou sentado em 21.000 erros do compilador , 300.000 linhas de mensagens de erro e 280 megabytes de RAM usados pelo compilador. E não mostra sinais de parar.
EDITAR:
Uma hora depois, agora com 36.000 erros de compilador , 504.000 linhas de mensagens de erro e 480 megabytes de RAM ... e ainda continua.
EDIT # 2:
Cerca de meia hora depois:
Estatísticas finais: 38.876 erros do compilador , 544.624 linhas de mensagens de erro, totalizando 48,8 megabytes de dados e 518,9 megabytes de RAM usados pelo compilador antes de travar .
fonte
28 bytes
Sabotando a biblioteca padrão:
Usando clang no OS X 10.9:
456 linhas de erros, 50 erros e um segfault do compilador !
Clang version:
fonte
Eu tropecei nisso por acidente:
No c ++ x11, ele produz 44kb de mensagens de erro, nas quais o compilador tenta dizer: Defina o espaço reservado para o primeiro argumento, se você o definir para o segundo.
Veja no ideone .
fonte
C ++
Com base na solução de BЈовић:
Arquivo: golf.cpp:
Executar isso no G ++ não terminará, no entanto, calculei a duração do erro que ele emitirá em aproximadamente 85 * 2 ^ 140 terabytes.
fonte
Modelos variáveis C ++ 11 (69 caracteres)
Configurando a profundidade máxima de instanciação do modelo, você pode definir o tamanho do erro. Aqui está um exemplo usando o GCC 4.8.1 com profundidade padrão do modelo (900):
Além disso, você pode adicionar mais dez caracteres e usar o underflow de número inteiro não assinado para aumentar o tamanho do erro:
Aqui está um exemplo em execução no ideone.
fonte
82 bytes: Este funciona de maneira semelhante à abordagem de Joey Adams , mas a mensagem de erro aumentará exponencialmente em relação a
-ftemplate-depth
(porquestd::set<T>
na verdade éstd::set<T, std::less<T>, std::allocator<T>>
).Pois
(x = -ftemplate-depth) >= 28
, haverá 1460 × 3 x-27 + 269x - 5381 bytes de mensagens de erro (compiladas pelo gcc 7.2.0). Ou seja, nas configurações padrão (x = 900), ele produzirá cerca de 4,9 × 10 419 bytes de mensagem de erro teoricamente.Observe que, sem a
return
instrução, as mensagens de erro serão produzidas apenas no final da compilação. (portanto, nas configurações padrão, você não receberá as mensagens - ficará sem memória primeiro.)Aviso: A compilação deste programa consumirá muita memória.
Experimente online!
fonte
map
parece estritamente mais ruim, poisstd::map<T,T>
é possívelstd::map<T,T,std::less<T>,std::allocator<std::pair<T,T>>>
obter recursão de 5 direções em vez de 3, por apenas mais 2 bytes.-ftemplate-depth=13
, 423.572 bytes em-ftemplate-depth=14
e 1.247.322 bytes em-ftemplate-depth=15
.map
variante gera 13.373.990 bytes na profundidade 14 e 66.759.871 bytes na profundidade 15.-ftemplate-depth=1024
, o que significa algo ao norte de 10 ^ 713 bytes com amap
variante. Eu acredito que isso significa que você ganha ...Isso produz uma saída infinita no GCC 5.2 e Clang 3.6 (no Clang exige
-ferror-limit=0
, no GCC funciona com as configurações padrão):fonte
Um arquivo chamado
a.cpp
. Código:Esta é uma bomba de forquilha onde n = 40.
fonte
=>
=>
ajuntar com
index_sequence parece ignorar o problema do limite de profundidade da instanciação do modelo
erros são assim: toda a sequência numérica de 0 ... C-1 parece impressa 4 * C vezes
e as seqüências numéricas podem ultrapassar o limite de profundidade da instanciação do modelo padrão, certamente porque é um componente interno:
fonte