Qual é o pior abuso de macros / pré-processadores do mundo real que você já encontrou?

Qual é o pior abuso de macros / pré-processadores do mundo real que você já encontrou (por favor, sem respostas inventadas do IOCCC * haha ​​*)?

Por favor, adicione um pequeno trecho ou história se for realmente divertido. O objective é ensinar algo em vez de sempre dizer às pessoas “nunca use macros”.


ps: Eu usei macros antes … mas geralmente eu me livre deles eventualmente quando eu tenho uma solução “real” (mesmo se a solução real for embutida, então ela se torna similar a uma macro).


Bônus: Dê um exemplo onde a macro era realmente melhor do que uma solução não-macro.

Pergunta relacionada: Quando as macros de C ++ são benéficas?

    De memory, parecia algo como isto:

    #define RETURN(result) return (result);} int myfunction1(args) { int x = 0; // do something RETURN(x) int myfunction2(args) { int y = 0; // do something RETURN(y) int myfunction3(args) { int z = 0; // do something RETURN(z) 

    Sim está certo, não há chaves de fechamento em nenhuma das funções. O destaque da syntax era uma bagunça, então ele usou o vi para editar (não vim, ele tem coloração de syntax!)

    Ele era um programador russo que trabalhou principalmente em linguagem assembly. Ele era fanático por salvar tantos bytes quanto possível porque já havia trabalhado em sistemas com memory muito limitada. “Era para satélite. Apenas muito poucos bytes, então usamos cada byte para muitas coisas.” (bit fiddling, reutilizando bytes de instruções da máquina para seus valores numéricos) Quando tentei descobrir que tipos de satélites, eu só consegui obter “Orbit orbiting. Para fazer órbita.”

    Ele tinha outras duas peculiaridades: um espelho convexo montado acima de seu monitor “Para saber quem está assistindo”, e uma súbita saída ocasional de sua cadeira para fazer dez flexões rápidas. Ele explicou este último como “Compiler found error in code. Isto é castigo”.

    Meu pior:

     #define InterlockedIncrement(x) (x)++ #define InterlockedDecrement(x) (x)-- 

    Passei dois dias da minha vida rastreando algum problema de contagem de refas COM multi-threaded porque algum idiota colocou isso em um arquivo de header. Não vou mencionar a empresa em que trabalhei na época.

    A moral dessa história? Se você não entender alguma coisa, leia a documentação e saiba mais sobre ela. Não apenas faça isso ir embora.

     #define ever (;;) for ever { ... } 
     #include  #define System S s;s #define public #define static #define void int #define main(x) main() struct F{void println(char* s){std::cout << s << std::endl;}}; struct S{F out;}; public static void main(String[] args) { System.out.println("Hello World!"); } 

    Desafio: Alguém pode fazer isso com menos definições e estruturas? 😉

     #define private public 
     #define if while 

    Foi piada jogado em alguém, não foi encontrado divertido por aqueles afetados

    O medonho:

     #define begin { #define end } /* and so on */ 

    Sério, se você quiser codificar em Pascal, compre um compilador Pascal, não destrua a linda linguagem C.

    Um ‘arquiteto’, um sujeito muito humilde, você conhece o tipo, tinha o seguinte:

     #define retrun return 

    porque ele gostava de digitar rápido. O cirurgião-cérebro costumava gritar com as pessoas que eram mais espertas do que ele (o que era praticamente todo mundo), e ameaçou usar seu cinto preto nelas.

    Mundo real? O MSVC tem macros em minmax.h, chamadas max e min , que causam um erro do compilador toda vez que pretendo usar a function padrão std::numeric_limits::max() .

    Uma mistura entre a syntax de Pascal e as palavras-chave francesas:

     #define debut { #define fin } #define si if( #define alors ){ #define sinon }else{ #define finsi } 

    Raymond Chen tem um bom discurso contra o uso de macros de controle de stream . Seu melhor exemplo é direto do código-fonte original do shell Bourne:

     ADDRESS alloc(nbytes) POS nbytes; { REG POS rbytes = round(nbytes+BYTESPERWORD,BYTESPERWORD); LOOP INT c=0; REG BLKPTR p = blokp; REG BLKPTR q; REP IF !busy(p) THEN WHILE !busy(q = p->word) DO p->word = q->word OD IF ADR(q)-ADR(p) >= rbytes THEN blokp = BLK(ADR(p)+rbytes); IF q > blokp THEN blokp->word = p->word; FI p->word=BLK(Rcheat(blokp)|BUSY); return(ADR(p+1)); FI FI q = p; p = BLK(Rcheat(p->word)&~BUSY); PER p>q ORF (c++)==0 DONE addblok(rbytes); POOL } 

    Eu gostaria de enviar para o concurso uma joia chamada chaos-pp , que implementa uma linguagem funcional por meio das macros do pré-processador.

    Um dos exemplos é calcular o 500º número de fibonacci inteiramente pelo pré-processador:

    O código original antes do pré-processador é assim:

     int main(void) { printf ("The 500th Fibonacci number is " ORDER_PP(8stringize(8to_lit(8fib(8nat(5,0,0))))) ".\n"); return 0; } 

    pré-processamento do arquivo obtemos o seguinte resultado (após uma longa espera):

     $ cpp -I../inc fibonacci.c 2>/dev/null | tail return fib_iter(n, 0, 1); } # 63 "fibonacci.c" int main(void) { printf ("The 500th Fibonacci number is " "139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125" ".\n"); return 0; } 

    Diretamente do Qt:

     #define slots /* */ #define signals /* */ 

    É muito bom interagir com outras bibliotecas como boost :: signals … Apenas um exemplo, existem muitas outras no Qt que criam códigos engraçados como:

     class X : public QObject { Q_OBJECT private slots: //... public signals: //... }; 

    E isso é C ++ … mas de repente:

     boost::signals::trackable 

    Não é mais válido C ++.

    O Windows.h tem muitas funções que abusam de macros.


    MrValdez está irritado com a macro GetObject encontrada no Windows.h

    A macro GetObject altera a function GetObject () para GetObjectA () ou GetObjectW () (dependendo se a compilation é compilada em não-unicode e unicode, respectivamente)

    MrValdez odeia ter que fazer antes da linha de function GetObject

     #undef GetObject Object *GetObject() 

    A alternativa é alterar o nome da function para algo como GetGameObject ()


    jdkoftinoff nos comentários acertaram: O problema é que todas as funções da API do Windows são macros.

    Adam Rosenfield mencionou que os problemas podem ser corrigidos definindo NOGDI, WIN32_LEAN_AND_MEAN, NOMINMAX, etc antes de include windows.h para remover os problemas.

     #define return if (std::random(1000) < 2) throw std::exception(); else return 

    isso é tão malvado. É random, o que significa que ele triggers em lugares diferentes o tempo todo, ele altera a declaração de retorno, que geralmente tem algum código nele que pode falhar por si só, ele altera a palavra-chave inocente que você nunca suspeitará e usa exceção de std space, portanto, você não tentará procurar em suas fonts para encontrar sua origem. Simplesmente shiny.

    Um colega de trabalho e eu encontrei essas duas gemas em alguns dos nossos códigos para streaming de objects. Essas macros foram instanciadas em todos os arquivos da class SINGLE que fizeram streaming. Não só esse código horrível foi espalhado por toda a nossa base de código, quando abordamos o autor original sobre ele, ele escreveu um artigo de 7 páginas em nosso wiki interno, defendendo isso como a única maneira possível de realizar o que ele estava tentando fazer aqui.

    É desnecessário dizer que ela já foi refatorada e não é mais usada em nossa base de código.

    Não seja jogado fora pelas palavras-chave destacadas. Isso é tudo uma macro

     #define DECLARE_MODIFICATION_REQUEST_PACKET( T ) \ namespace NameSpace \ { \ \ class T##ElementModificationRequestPacket; \ } \ \ DECLARE_STREAMING_TEMPLATES( IMPEXP_COMMON_TEMPLATE_DECLARE, NameSpace::ElementModificationRequestPacket, OtherNameSpace::NetPacketBase ) \ DLLIMPEXP_COMMON_TEMPLATE_DECLARE( NameSpace::ElementModificationRequestPacket ) \ DECLARE_AUTOGENERATION_TEMPLATES( DLLIMPEXP_COMMON_TEMPLATE_DECLARE, NameSpace::T##ModificationRequestPacket, NameSpace::ElementModificationRequestPacket ) \ \ namespace NameSpace { \ class DLLIMPEXP_COMMON T##ModificationRequestPacket : public ElementModificationRequestPacket\ { \ public: \ T##ModificationRequestPacket( NetBase * pParent ) \ : ElementModificationRequestPacket( pParent ), m_Gen() {} \ \ T##ModificationRequestPacket( NetBase * pParent, \ Action eAction, \ const T & rT ) \ : ElementModificationRequestPacket( pParent, eAction, rT ), m_Gen() {} \ \ T##ModificationRequestPacket( const T##ModificationRequestPacket & rhs ) \ : ElementModificationRequestPacket( rhs ), m_Gen() {} \ \ virtual ~T##ModificationRequestPacket( void ) {} \ \ virtual Uint32 GetPacketTypeID( void ) const \ { \ return Net::T##_Modification_REQUEST_PACKET; \ } \ \ virtual OtherNameSpace::ClassID GetClassID ( void ) const \ { \ return OtherNameSpace::NetBase::GenerateHeader( OtherNameSpace::ID__LICENSING, \ Net::T##_Modification_REQUEST_PACKET ); \ } \ \ virtual T##ModificationRequestPacket * Create( void ) const \ { return new T##ModificationRequestPacket( m_pParent ); } \ \ T##ModificationRequestPacket() {} \ \ protected: \ OtherNameSpace::ObjectAutogeneration m_Gen; \ \ friend class OtherNameSpace::StreamingBase::StreamingClassInfoT; \ OtherNameSpace::StreamingBase::Streaming > m_Stream; \ \ }; \ } \ DLLIMPEXP_COMMON_TEMPLATE_DECLARE( ThirdNameSpace::ListenerBase ) \ DLLIMPEXP_COMMON_TEMPLATE_DECLARE( ThirdNameSpace::BroadcasterT ) \ typedef ThirdNameSpace::BroadcasterT T##ModifiedBroadcaster; #define IMPLEMENT_MODIFICATION_REQUEST_PACKET( T ) \ DLLIMPEXP_COMMON_TEMPLATE_INSTANTIATE( NameSpace::ElementModificationRequestPacket ) \ DLLIMPEXP_COMMON_TEMPLATE_INSTANTIATE( ThirdNameSpace::ListenerBase ) \ DLLIMPEXP_COMMON_TEMPLATE_INSTANTIATE( ThirdNameSpace::BroadcasterT ) \ INSTANTIATE_STREAMING_TEMPLATES( DLLIMPEXP_COMMON_TEMPLATE_INSTANTIATE, NameSpace::ElementModificationRequestPacket, OtherNameSpace::NetPacketBase ) \ INSTANTIATE_AUTOGENERATION_TEMPLATES( DLLIMPEXP_COMMON_TEMPLATE_INSTANTIATE, NameSpace::T##ModificationRequestPacket, NameSpace::ElementModificationRequestPacket ) 

    Atualização (17 de dezembro de 2009):

    Mais boas notícias sobre este autor macro hediondo. A partir de agosto, o empregado responsável por essa monstruosidade foi demitido.

    Eu mesmo fiz o seguinte, e acho que aprendi algo com isso.

    Em 1992, escrevi um pequeno interpretador de Lisp. Não foi implementado em C normal, mas em uma linguagem semelhante a C interpretada. Essa linguagem semelhante a C usava o pré-processador C padrão.

    O interpretador Lisp, claro, continha o carro functions, que é usado em Lisp para retornar o primeiro elemento de uma lista, e cdr , que retorna o resto da lista. Eles foram implementados assim:

     LISPID car(LISPID id) { CHECK_CONS("car", 1, id); return cons_cars[id - CONS_OFFSET]; } /* car */ LISPID cdr(LISPID id) { CHECK_CONS("cdr", 1, id); return cons_cdrs[id - CONS_OFFSET]; } /* cdr */ 

    (Os dados foram armazenados em matrizes, uma vez que não havia estruturas. CONS_OFFSET é a constante 1000.)

    car e cdr são usados ​​freqüentemente em Lisp, e são curtos, e como as chamadas de function não eram muito rápidas na linguagem de implementação, eu otimizava meu código implementando essas duas funções Lisp como macros:

     #define car(id) (CHECK_CONS("car", 1, (id)), cons_cars[(id) - CONS_OFFSET]) #define cdr(id) (CHECK_CONS("car", 1, (id)), cons_cdrs[(id) - CONS_OFFSET]) 

    CHECK_CONS verifica se seu argumento é realmente uma lista e, como esse também é usado com frequência no interpretador, e é curto, eu o escrevi também como uma macro:

     #define CHECK_CONS(fun, pos, arg) \ (!IS_CONS(arg) ? \ LISP_ERROR("Arg " + pos + " to " + fun + \ " must be a list: " + lispid2string(arg)) : 0) 

    IS_CONS e LISP_ERROR também foram usados ​​com freqüência, então eu os criei em macros também:

     #define IS_CONS(id) \ ( intp(id) && (id) >= CONS_OFFSET \ && ((id) - CONS_OFFSET) < sizeof(cons_cars)) #define LISP_ERROR(str) (throw((str) + "\n")) 

    Parece razoável?

    Mas então, por que todo o sistema travou nesta linha:

     id2 = car(car(car(car((id1)))); 

    Eu trabalhei muito tempo para encontrar o problema, até que finalmente chequei o que essa linha curta foi expandida para o pré-processador. Foi expandido para uma linha de 31370 caracteres, que eu dividi aqui em linhas (502 delas) para maior clareza:

     id2 = ((!(intp( (((!(intp( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) && ( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) >= 1000 && (( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000])) - 1000]))) && ( (((!(intp( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) && ( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) >= 1000 && (( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000])) - 1000]))) >= 1000 && (( (((!(intp( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) && ( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) >= 1000 && (( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000])) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) && ( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) >= 1000 && (( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000])) - 1000])) - 1000])))) + "\n")) : 0), cons_cars[(((!(intp( (((!(intp( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) && ( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) >= 1000 && (( (((!(intp( (id1)) && ( (id1)) >= 1000 && (( (id1)) - 1000) < sizeof(cons_cars)) ? (throw(("Arg " + 1 + " to " + "car" + " must be a list: " + lispid2string( (id1))) + "\n")) : 0), cons_cars[(id1) - 1000]))) - 1000) < sizeof(cons_cars)) 

    I once had to port a C application from unix to windows, the specific nature of which shall remain unnamed to protect the guilty. The guy who wrote it was a professor unaccustomed to writing production code, and had clearly come to C from some other language. It also happens that English wasn’t his first language, though the country he came from the majority of people speak it quite well.

    His application made heavy use of the preprocessor to twist the C language into a format he could better understand. But the macros he used the most were defined in a header file named ‘Thing.h’ (seriously), which included the following:

     #define I Any void_me #define thou Any void_thee #define iam(klas) klas me = (klas) void_me #define thouart(klas) klas thee = (klas) void_thee #define my me -> #define thy thee -> #define his him -> #define our my methods -> #define your thy methods -> 

    …which he then used to write monstrosities like the following:

     void Thing_setName (I, const char *name) { iam (Thing); if (name != my name) { Melder_free (my name); my name = Melder_wcsdup (name); } our nameChanged (me); } void Thing_overrideClass (I, void *klas) { iam (Thing); my methods = (Thing_Table)klas; if (! ((Thing_Table) klas) -> destroy) ((Thing_Table) klas) -> _initialize (klas); } 

    The entire project (~60,000 LOC) was written in a similar style — marco hell, weird names, Olde-English jargon, etc. Fortunately we were able to throw the code out since I found an OSS library which performed the same algorithm dozens of times faster.

    (I’ve copied and edited this answer which I originally made on this question ).

    The worst I’ve ever encountered was in a product containing a suite of executables where the designated technical leader hadn’t figured out libraries.

    Instead, he had sets of files that were shared in several Visual Source Safe folders. He then realised they needed to behave slightly differently for each application.

    There’s a number of refactoring steps you could apply here.

    Instead, he used #ifdefs

      void DisplayLoadError() { #if defined __TIMETABLE_EDITOR MessageBox("Timetable Editor failed to load the correct timetable", MB_ERROR); #else if defined __SCHEDULESET_EDITOR MessageBox("Schedule Set Editor faied to load the correct Schedule Set", MB_ERROR); #else if defined __ROSTER_EDITOR MessageBox("Roster Editor failed to load the correct Roster", MB_ERROR); #endif } 

    The use of the LINE preprocessor to generate unique ID for messages passed over the network:

     NetworkMessages.h #define MSG_LOGIN __LINE__ #define MSG_LOGOUT __LINE__ #define MSG_CHAT __LINE__ 

    This is an example where the macro really was better than a non-macro solution:

    In a non-macro solution classs, functions and variables have to be built to keep track of what ID the message is. The developer may or may not make the message ID tracking complicated whereas this is easier to read and debug.

    In addition, its easier to add new messages just by adding the message into the source.

    The disadvantage of this situation is that the file has to be included in all code that uses messages. Compile time would increase whenever a message is edited.

    One fairly bad example:

     #ifdef __cplusplus #define class _vclass #endif 

    This allows a C structure that contains a member variable called class to be handled by a C++ compiler. There are two headers with this construct in it; one of them also contains ‘#undef class’ at the end and the other doesn’t.

    In one year of the International Obfuscated C Coding Contest, there was an entry where the entire program was:

    P

    With the proviso that you could define P in the makefile to be whatever program you wanted.

    As I recall, it won in one of the categories, and the next year a rule had popped up disallowing that style of entry.

    (Edit: six months later or something… I’m sure the “No IOCCC” thing wasn’t in the main question when I wrote this…)

    I was bored one day and was playing around with blocks in Objective-C…

     #define Lambda(var, body) [^ id(id (var)) { return (body);} copy] #define Call(f, arg) ((id(^)(id))(f))(arg) #define Int(num) [NSNumber numberWithInteger:(num)] #define Mult(a, b) Int([(a) integerValue] * [(b) integerValue]) #define Add(a, b) Int([(a) integerValue] + [(b) integerValue]) #define Sub1(n) Int([(n) integerValue] - 1) #define Add1(n) Int([(n) integerValue] + 1) #define If(cond, thenblock, elseblock) ([(cond) integerValue] ? (thenblock) : (elseblock)) #define Cons(car, cdr_) [[ConsType alloc] initWithCar:(car) cdr:(cdr_)] #define Car(list) [(list) car] #define Cdr(list) [(list) cdr] #define Define(var, value) id var = (value) #define Nullq(value) Int(value == nil) 

    allowing “interesting” things like:

     Define(Y, Lambda(f, Call(Lambda(x, Call(x, x)), Lambda(x, Call(f, Lambda(y, Call(Call(x, x), y))))))); Define(AlmostTotal, Lambda(f, Lambda(list, If(Nullq(list), Int(0), Add(Car(list), Call(f, Cdr(list))))))); Define(Total, Call(Y, AlmostTotal)); Print(Call(Total, Cons(Int(4), Cons(Int(5), Cons(Int(8), nil))))); 

    (some function and class definitions not shown for sake of brevity)

    The worst one I saw was the non-use 🙂

    Someone wrote a strcpy (I think that was it… over 10 years ago now) function inside of a method (because they didn’t want the overhead of calling strcpy… sigh).

    They clued in that it wouldn’t work for Japanese characters so they added an “if” at the start to do ASCII or Unicode. At that point the code was about a screen long… likely killing cache coherency and erasing his supposed savings for the inlining of the code.

    The code was identical save for the types (so should have used a macro).

    Of course the strcpy that they wrote was much much much slower than the hand tuned assembler one that was in the standard library…

    Of course if they had just done it all as a macro it could have been replaced with a call to strcpy…

    Of course I quit the company (not directly because of that…)

    The obligatory

     #define FOR for 

    e

     #define ONE 1 #define TWO 2 ... 

    Quem sabia?

     #define TRUE 0 // dumbass 

    The person who did this explained himself some years later – most (if not all) C library functions return 0 as an indication that everything went well. So, he wanted to be able to write code like:

     if (memcpy(buffer, packet, BUFFER_SIZE) == TRUE) { ; // rape that packet } 

    Needless to say, nobody in our team (tester or developer) ever dared to glance at his code again.

    I maintain code that has gotos in macros. So a function will have a label at the end but no visible goto in the function code. To make matters worse the macro is at the end of other statements usually off the screen unless you scroll horizontally.

     #define CHECK_ERROR if (!SomeCondition) goto Cleanup void SomeFunction() { SomeLongFunctionName(ParamOne, ParamTwo, ParamThree, ParamFour); CHECK_ERROR //SomeOtherCode Cleanup: //Cleanup code } 
     #include  #define public_static_void_main(x) int main() #define System_out_println(x) std::cout << x << std::endl public_static_void_main(String[] args) { System_out_println("Hello World!"); } 

    By a classmate who failed to understand the rules about magic numbers:
    #define TWO_HUNDRED_AND_EIGHTY_THREE_POINT_ONE 283.1

    ASA – http://www.ingber.com/#ASA

    You really have to download it to appreciate it. The entire work flow is determined by macros. It is completely unreadable. As an example –

      if (asa_open == FALSE) { asa_open = TRUE; ++number_asa_open; #if ASA_PRINT if (number_asa_open == 1) { /* open the output file */ #if USER_ASA_OUT if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) { #if INCL_STDOUT ptr_asa_out = stdout; #endif /* INCL_STDOUT */ } else { #if ASA_SAVE ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a"); #else ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "w"); #endif } #else /* USER_ASA_OUT */ if (!strcmp (ASA_OUT, "STDOUT")) { #if INCL_STDOUT ptr_asa_out = stdout; #endif /* INCL_STDOUT */ } else { #if ASA_SAVE ptr_asa_out = fopen (ASA_OUT, "a"); #else ptr_asa_out = fopen (ASA_OUT, "w"); #endif } #endif /* USER_ASA_OUT */ } else { #if USER_ASA_OUT if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) { #if INCL_STDOUT ptr_asa_out = stdout; #endif /* INCL_STDOUT */ } else { ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a"); } #else if (!strcmp (ASA_OUT, "STDOUT")) { #if INCL_STDOUT ptr_asa_out = stdout; #endif /* INCL_STDOUT */ } else { ptr_asa_out = fopen (ASA_OUT, "a"); } #endif fprintf (ptr_asa_out, "\n\n\t\t number_asa_open = %d\n", number_asa_open); } #endif /* ASA_PRINT */ } else { ++recursive_asa_open; #if ASA_PRINT if (recursive_asa_open == 1) { /* open the output file */ #if ASA_SAVE #if USER_ASA_OUT if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) { #if INCL_STDOUT ptr_asa_out = stdout; #endif /* INCL_STDOUT */ } else { ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a"); } #else if (!strcmp (ASA_OUT, "STDOUT")) { #if INCL_STDOUT ptr_asa_out = stdout; #endif /* INCL_STDOUT */ } else { ptr_asa_out = fopen (ASA_OUT, "a"); } #endif #else /* ASA_SAVE */ #if USER_ASA_OUT if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) { #if INCL_STDOUT ptr_asa_out = stdout; #endif /* INCL_STDOUT */ } else { 

    etc etc.

    And that is just setting up the options. the entire program is like that.