Qual è il peggior abuso di macro / pre-processore nel mondo reale che tu abbia mai incontrato?

Qual è il peggiore uso di macro / pre-processore nel mondo reale che abbia mai incontrato (per favore non ci sono risposte IOCCC inventate * haha ​​*)?

Per favore aggiungi un breve frammento o una storia se è davvero divertente. L’objective è insegnare qualcosa invece di dire sempre alle persone “non usare mai macro”.


ps: ho usato macro prima … ma di solito me ne sbarazzerò quando avrò una soluzione “reale” (anche se la soluzione reale è in linea in modo che diventi simile a una macro).


Bonus: fai un esempio in cui la macro era davvero migliore di una soluzione non macro.

Domanda correlata: quando sono utili i macro C ++?

    Dalla memoria, assomigliava a questo:

    #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) 

    Sì, è vero, senza parentesi graffe in nessuna delle funzioni. L’evidenziazione della syntax era un disastro, quindi ha usato vi per modificare (non vim, ha la colorazione della syntax!)

    Era un programmatore russo che aveva lavorato principalmente in linguaggio assembly. Era un fanatico nel salvare il maggior numero ansible di byte perché in precedenza aveva lavorato su sistemi con memoria molto limitata. “Era per il satellite. Solo pochi byte, quindi usiamo ogni byte per molte cose.” (un po ‘di manipolazione, riutilizzando i byte di istruzione della macchina per i loro valori numerici) Quando ho cercato di scoprire quali tipi di satelliti, sono riuscito a ottenere solo “Orbitare in satellite.” Per fare in orbita. ”

    Aveva altre due stranezze: uno specchio convesso montato sopra il suo monitor “Per sapere chi sta guardando”, e un’occasionale uscita improvvisa dalla sua sedia per fare una rapida dieci flessioni. Ha spiegato quest’ultimo come “Errore nel compilatore trovato nel codice. Questa è una punizione”.

    Il mio peggio:

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

    Ho passato due giorni della mia vita a rintracciare alcuni problemi di conteggio dei reflets COM multi-thread perché alcuni idiota lo hanno inserito in un file di intestazione. Non menzionerò la compagnia per cui ho lavorato in quel momento.

    la morale di questa storia? Se non capisci qualcosa, leggi la documentazione e informala. Non lasciarlo andare via.

     #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!"); } 

    Sfida: qualcuno può farlo con meno definizioni e strutture? 😉

     #define private public 
     #define if while 

    E ‘stato scherzato su qualcuno, non è stato trovato divertente da parte delle persone colpite

    L’orribile:

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

    Seriamente, se vuoi programmare in Pascal, comprare un compilatore Pascal, non distruggere il bellissimo linguaggio C.

    Un ‘architetto’, un tipo molto umile, tu conosci il tipo, ha avuto il seguente:

     #define retrun return 

    perché gli piaceva digitare veloce. Il chirurgo del cervello amava urlare alle persone che erano più intelligenti di lui (che era praticamente tutti) e minacciavano di usare la sua cintura nera su di loro.

    Mondo reale? MSVC ha macro in minmax.h, chiamate max e min , che causano un errore del compilatore ogni volta che intendo utilizzare la funzione standard std::numeric_limits::max() .

    Un mix tra syntax Pascal e parole chiave francesi:

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

    Raymond Chen ha una vera e propria smania contro l’uso di macro di controllo del stream . Il suo miglior esempio è direttamente dal codice sorgente della shell Bourne originale:

     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 } 

    Vorrei presentare per il concorso una gem chiamata chaos-pp , che implementa un linguaggio funzionale per mezzo delle macro del preprocessore.

    Uno degli esempi è il calcolo del 500 ° numero di fibonacci interamente dal preprocessore:

    Il codice originale prima del preprocessore ha questo aspetto:

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

    preelaborando il file otteniamo il seguente risultato (dopo un’attesa piuttosto lunga):

     $ 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; } 

    Direttamente da Qt:

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

    È davvero bello interagire con altre librerie come boost :: signals … Solo un esempio, ci sono molti altri in Qt che creano codice dall’aspetto divertente come:

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

    E questo è C ++ … ma all’improvviso:

     boost::signals::trackable 

    Non è più valido C ++.

    Windows.h ha un sacco di funzioni che hanno abusato di macro.


    MrValdez è infastidito dalla macro GetObject trovata in Windows.h

    La macro GetObject modifica la funzione GetObject () in GetObjectA () o GetObjectW () (a seconda che la compilazione sia compilata in non-unicode e unicode, rispettivamente)

    MrValdez odia doverlo fare prima della linea funzione GetObject

     #undef GetObject Object *GetObject() 

    L’alternativa è di cambiare il nome della funzione in qualcos’altro come GetGameObject ()


    jdkoftinoff nei commenti l’ha inchiodato: il problema è che tutte le funzioni API di Windows sono macro.

    Adam Rosenfield ha affermato che i problemi possono essere risolti definendo NOGDI, WIN32_LEAN_AND_MEAN, NOMINMAX, ecc prima di includere windows.h per rimuovere i problemi.

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

    questo è solo così male. È casuale, il che significa che spara sempre in posti diversi, cambia la dichiarazione di ritorno, che di solito ha un codice su di esso che potrebbe fallire da solo, cambia la parola chiave dall'aspetto innocente di cui non sarai mai sospettoso e che usa eccezione dallo spazio standard in modo da non provare a cercare tra le fonti per trovare la fonte. Semplicemente geniale.

    Un collega e ho trovato queste due gemme in alcuni dei nostri codici per lo streaming di oggetti. Queste macro sono state istanziate in OGNI file di class SINGLE che ha effettuato lo streaming. Non solo questo orribile codice è emerso in tutta la nostra base di codice, quando ci siamo avvicinati all’autore originale, ha scritto un articolo di 7 pagine sulla nostra wiki interna, difendendo questo come l’unico modo ansible per realizzare ciò che stava tentando di fare qui.

    Inutile dire che da allora è stato rifattorizzato e non è più utilizzato nella nostra base di codice.

    Non essere espulso dalle parole chiave evidenziate. Questa è TUTTA una 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 ) 

    Aggiornamento (17 dicembre 2009):

    Altre buone notizie su questo orribile autore di macro. A partire da agosto, il dipendente responsabile di questa mostruosità è stato licenziato.

    Ho fatto il seguente me stesso, e penso di aver imparato qualcosa da esso.

    Nel 1992 circa scrissi un piccolo interprete Lisp. Non è stato implementato nella normale C, ma in un linguaggio simile a C interpretato. Questo linguaggio simile a C utilizzava il pre-processore C standard, però.

    L’interprete Lisp conteneva ovviamente le funzioni car , che è usato in Lisp per restituire il primo elemento in una lista, e cdr , che restituisce il resto della lista. Sono stati implementati in questo modo:

     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 */ 

    (I dati sono stati archiviati in array, poiché non vi erano strutture CONS_OFFSET è la costante 1000.)

    auto e cdr sono usati frequentemente in Lisp, e sono brevi, e poiché le chiamate di funzione non erano molto veloci nel linguaggio di implementazione, ho ottimizzato il mio codice implementando queste due funzioni Lisp come macro:

     #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 che il suo argomento sia effettivamente una lista, e dal momento che quello è anche usato frequentemente nell’interprete, ed è breve, l’ho scritto anche come macro:

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

    Anche IS_CONS e LISP_ERROR sono stati usati frequentemente, quindi li ho trasformati anche in macro:

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

    Sembra ragionevole?

    Ma poi, perché l'intero sistema si è bloccato su questa linea:

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

    Ho lavorato a lungo per trovare il problema, fino a quando non ho finalmente verificato a quale linea di demarcazione era stata estesa dal pre-processore. È stato espanso con una linea di 31370 caratteri, che ho qui suddiviso in linee (502 di esse) per chiarezza:

     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 performsd 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 ... 

    Who knew?

     #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 { 

    ecc., ecc.

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