Che cosa C ??!??! operatore di fare?

Ho visto una riga di C che sembrava questo:

!ErrorHasOccured() ??!??! HandleError();

Sia stato compilato correttamente e sembra funzionare ok. E non mi sembra di controllare se si è verificato un errore, e se ne gestisce. Ma io non sono davvero sicuro di cosa fare o come farlo. Lo fa apparire come il programmatore sta cercando di esprimere i loro sentimenti su errori.

Non ho mai visto la ??!??! prima in qualsiasi linguaggio di programmazione, e non riesco a trovare la documentazione per ovunque. (Google non aiuta con i termini di ricerca come ??!??!). Che cosa fa e che cosa fa l’esempio di codice riportato di lavoro?

  • esprimere le vostre emozioni in qualche altro modo, non utilizzare trigrammi, scrivere un codice che può essere compreso dall’uomo
  • come potete pretendere che !ErrorHasOccurred() ??!???! HandleError(); per compilare? Che ??! ??? !. Si rivela il punto?
  • Vi suggerisco di leggere la pulizia del codice. ErrorHasOccured() deve essere rielaborato ErrorHasNotOccured() quindi ripulire il punto esclamativo…chi ha il tempo di capire tutti questi operatori??!
  • Io preferisco ErrorHasOccured() && HandleError() me. Che anche come Lua fa.
  • spostando la negazione in nome della funzione e non per fare la pulizia del codice, piuttosto il contrario.
  • IMHO un vero e proprio uso di trigrammi anche oggi: quando qualche pezzo di codice funziona DAVVERO è possibile aumentare la probabilità che nessuno tenta di riscrivere/ottimizzare/invalidare tale codice. Limita di molto il vantaggio, anzi.
  • “leggere un codice pulito” sì certo, perché non è totalmente opinabile e soggettivo argomento che si può solo scrivere una ricetta per.
  • Più noto come “WTF Operatore”
  • Una nota per chi ha finito qui dopo una lotta fino alla morte con il loro motore di ricerca: SymbolHound può aiutare con il simbolico ricerche.
  • Purtroppo questo gioiello di un programma non funziona in C++17 e più recenti.

 

4 Replies
  1. 1514

    ??! è un trigramma che si traduce in |. Così si dice:

    !ErrorHasOccured() || HandleError();

    che, a causa di un cortocircuito, è equivalente a:

    if (ErrorHasOccured())
        HandleError();

    Guru della Settimana (tratta C++, ma è rilevante in questa sede, dove ho preso questo.

    Possibile origine di trigrammi o come @DwB indica nei commenti è più probabile a causa di EBCDIC essere difficile (di nuovo). Questo discussione su developerworks di IBM consiglio sembra supportare questa teoria.

    Da ISO/IEC 9899:1999 §5.2.1.1, nota 12 (h/t @Random832):

    Il trigramma sequenze di attivare l’input di caratteri che non sono definiti nel Invariante Codice Impostato come
    descritto nella norma ISO/IEC 646, che è un sottoinsieme di sette bit di NOI codice ASCII set.

    • Trigrammi originariamente necessario nel caso in cui la tastiera non hanno ad esempio un ‘|’ simbolo. Qui è il programmatore deliberatamente di essere fastidioso o bizzarre editor di ‘funzione’
    • Quindi affidarsi || corto circuito o qualcosa del genere?
    • Sì, è equivalente a if (ErrorHasOccured()) HandleError(). Per fortuna di solito solo incontro questo linguaggio in codice perl.
    • corretto. Se !ErrorHasOccured() risolve true poi è corto circuiti, altrimenti HandleError() è quindi chiamato.
    • Trigrammi sono stati aggiunti per EBCDIC computer.
    • anche in Perl, sicuramente è quello che unless è per?
    • Non stavo cercando di considerarla. È proprio dove sono più spesso visto, ad esempio,open(...) or die(...).
    • Non è necessariamente EBCDIC – il set di caratteri che richiedono trigrammi quasi esattamente corrisponde al set di caratteri che non sono invarianti in ISO 646 (cioè il vecchio ‘nazionale’ in ascii standard).
    • la norma ha una nota dicendo: Il trigramma sequenze di attivare l’input di caratteri che non sono definiti nel Invariante Codice Impostato come descritto nella norma ISO/IEC 646, che è un sottoinsieme di sette bit US ASCII set di codice.
    • Tedesco e svedese varianti avuto la lettera ‘ö’ in quella posizione in codice.
    • Perfettamente leggibile alternativa sarebbe ErrorHasOccurred() && HandleError(); Che è, se sei abituato a shell scripting. 🙂
    • Cosa Yam ha detto (solo nel mio caso, sostituire “shell” con “ruby”).
    • Che cosa è fermare il compilatore di decidere che la chiamata a HandleError() deve eseguire per primo?
    • Gli operatori booleani sono rigorosamente valutati LTR, IIRC.
    • Basta notare che molti standard di codifica in particolare vietare l’uso di Trigrammi e Digrammi, e molti compilatori & static analizzatori di bandiera il loro uso.
    • Io ancora non riesco a leggere che: !ErrorHasOccured() || HandleError(); – Come è possibile leggere in inglese normale? “Se c’è un errore O errore di handle?’ – se c’è un errore o è in grado di gestire un errore farlo?
    • Leggere come “non ErrorHasOcurred o si deve HandleError”, @SparkyRobinson.
    • in perl sarebbe più espressivo di scrittura: handleError() if errorHasOccured() o qualcosa di simile handleError() unless isSuccess()
    • Si legge, come si afferma: (errore non verificato) o (maniglia di errore).
    • man cobfusc su digrammi: L’emendamento n. 1 (1994) modifiche agli standard ANSI X3.159-1989 (“ANSI C89”) sono supportati solo da alcuni compilatori C (BSD 1 luglio 2001).
    • IBM filo di collegamento è morto. Si può sostituire?
    • Non valido dal C++17 😐
    • Il C++ non è C. Anche se C è valido C++. Non è solo che il tubo non può essere sulla tastiera, 3270 terminali sono 2 tubi, e c’è il rischio che possano essere utilizzati quando passate da ASCII terra. Come un a parte, ci sono altre sostituzioni di caratteri, e ho codificato C on un Cyber dover utilizzare # per le citazioni all’inizio della mia esperienza.

  2. 426

    Bene, perché questo esiste, in generale, è probabilmente diverso perché esiste nel tuo esempio.

    Tutto è iniziato mezzo secolo fa, con la riproposta di hardcopy terminali di comunicazione come computer interfacce utente. Nella fase iniziale Unix e C era che era ASR-33 Teletype.

    Questo dispositivo è stato lento (10 cps) e rumoroso e brutto e la sua visione del set di caratteri ASCII chiuso al 0x5f, quindi, non aveva (guardate attentamente la foto) nessuno dei tasti:

    { | } ~ 

    I trigrammi sono stati definiti per risolvere un problema specifico. L’idea era che programmi in C potrebbe usare l’ASCII sottoinsieme trovare sul ASR-33 e in altri ambienti mancanti alti valori ASCII.

    Il tuo esempio è in realtà due di ??!, ogni significato |, in modo che il risultato è ||.

    Tuttavia, le persone che la scrittura di codice C, quasi per definizione, aveva moderne attrezzature,1 quindi la mia ipotesi è: qualcuno in mostra o divertente themself, lasciando una sorta di uovo di Pasqua nel codice per voi per trovare.

    Di sicuro ha lavorato, ha portato ad una popolarissima in MODO domanda.

    Che cosa C ??!??! operatore di fare?

                                                ASR-33 Teletype


    1. Per quella materia, i trigrammi sono stati inventati da ANSI comitato, che ha incontrato prima dopo C a diventare un successo clamoroso, in modo che nessuna delle originali codice C o programmatori averlo usato.

    • Non è il solo caso di caratteri mancanti, la tastiera e il set di caratteri. Il Commodore 64 è probabilmente più familiare per un sacco di persone nella loro fine degli anni trenta e verso l’alto – il carattere visualizzato imposta sia mancavano le parentesi graffe (e, probabilmente, il bar e il carattere tilde troppo) – in questo caso, perché il “ASCII” non ASCII. In ECMA-6 (quasi sempre chiamato ASCII, ma non US-ASCII) c’erano 18 regione-codici specifici, ma non so che codici sono stati. L’unica cosa che posso dire con certezza – il Britannico “ASCII”, # è stato sostituito con £. In altre regioni, magari “ASCII” non aveva bretelle etc.
    • Simile ATASCII set di caratteri per computer Atari a 8 bit, inoltre, mancavano { } come ~ e `.
    • Vedere questi due articoli di Wikipedia. Sto abbastanza vecchio da ricordare ancora l’era di 7 bit nazionale di caratteri (anche se sono sicuro che sono ancora presenti in alcune scuro unswept angoli), e il libro ho imparato a C ritenuto necessario mettere in guardia circa la possibilità di if (x || y) { a[i] = '\0'; } cercando come if (x öö y) ä aÄiÅ = 'Ö0'; å sbagliato il set di caratteri.
    • beh, sul C64 si potrebbe riscrivere il set di caratteri, in modo che si può utilizzare qualunque sia la codifica che ti piace 🙂
    • Un’altra interessante nota storica è che Unix (che è stato il grande piattaforma C ha guidato in su) potrebbe essere stato il primo sistema di qualsiasi significato (e forse il primo in assoluto) a default alfabetico valori inferiori caso, piuttosto che in maiuscolo. Anche se non ho visto con i miei occhi contemporanea, sistemi, credo che questo è stato un vero e proprio segno di ricercatezza. Oltre ad essere davvero l’unico decente OS, Unix anche convertito il caso superiore a inferiore, piuttosto che viceversa. Quei ragazzi sono stati davvero cool.
    • Storia divertente, devo dire ya… IBM RS/6000 workstation XL Fortran compiler è stato sviluppato dalla XL C compiler. Nelle prime versioni, accidentalmente lasciato il trigramma di elaborazione, in modo da ci sono stati alcuni legit Fortran sequenze di caratteri (in una stringa letterale, IIRC) che sono stati erroneamente interpretati come C trigrammi, conducendo alcuni bug interessanti!
    • So che la Commodore è venuto dopo, ma se superiore o inferiore, per caso era il default dipendeva il set di caratteri che è stato selezionato. Inoltre, il rapporto tra schermo codici di carattere e il codice utilizzato dal “getch/putch” metodi equivalenti nel Kernel è stato piuttosto bizzarro. Apple computer putch equivalente utilizzato schermata dei codici, che aveva bit 7 per il testo normale. Inoltre, fino al 80 colonne carta è stato rilasciato per il //e, anche di macchine, che potrebbe mostrare la minuscola potrebbe farlo solo in non-inversa di testo.
    • Nel caso In cui volete rinfrescarvi la memoria, l’esatta codici, standard ECMA-6 è disponibile online 🙂
    • Una bella risposta, ma di sicuro sembra che il tasto a destra di 0 è in realtà un | chiave (con * sopra)…
    • che in realtà è un : — migliori foto qui: pdp8.net/asr33/pics/kbd_top.shtml?large
    • Mi piace il …. ri – girare …
    • Trigrammi sono orribili. L’unico personaggio che deve essere synthesizable all’interno di stringhe tra virgolette è la barra rovesciata (“meta”) carattere, e che avrebbe potuto essere ospitati da dire che se la prima riga del file contiene un solo carattere, e il personaggio è una barra rovesciata (o non è in C set di caratteri, il compilatore deve trattare il personaggio come meta carattere da allora in poi. Tutti gli altri personaggi, poi, potrebbe essere reso disponibile come “barra” sfugge. I compilatori che non sanno niente di questa funzionalità potrebbe semplicemente ignorare una linea che contiene una barra rovesciata e nient’altro.
    • L’aneddoto che ho sentito dire da qualcuno che è stato su C90 comitato è che con il tempo di standardizzazione ISO, che ancora non ha potuto escludere trigrammi. Il problema è che alcune tastiere per alcune lingue (per esempio lingue Nordiche e tedesco) mancavano ancora diversi simboli esotici come |, { ecc, sacrificato a favore per avere chiavi di tutte le lettere del loro alfabeto.

  3. 156

    È un C trigramma. ??! è |, così ??!??! è l’operatore ||

    • perché qualcuno dovrebbe utilizzare ??! invece di | ???/
    • trigramma vengo da un periodo in cui alcuni tasti non hanno tutte le chiavi che hanno ora. Inoltre, hels quando alcuni editor di testo riservato caratteri speciali per le cose speciali. È per lo più una reliquia del passato e un concorso abilitante 😉
    • Perché alcune tastiere a quanto pare non hanno “|” per cui alcune persone non hanno altra scelta, ma per testata la tastiera ripetutamente fino a quando un trigramma verifica che dà loro i simboli di cui hanno bisogno.
  4. 134

    Come già detto ??!??! è essenzialmente due trigrammi (??! e ??! di nuovo) mushed insieme che vengono sostituiti tradotto per ||, io.e il logico O, per il preprocessore.

    La seguente tabella contiene ogni trigramma dovrebbe evitare ambiguità alternativo trigramma combinazioni:

    Trigraph   Replaces
    
    ??(        [
    ??)        ]
    ??<        {
    ??>        }
    ??/       \
    ??'        ^
    ??=        #
    ??!        |
    ??-        ~

    Fonte: C: Un Manuale di Riferimento per la 5 ° Edizione

    Così un trigramma che sembra ??(??) finalmente mappa per [], ??(??)??(??) saranno rimpiazzati da [][] e così via, si ottiene l’idea.

    Dal trigrammi sono sostituite durante la pre-elaborazione si potrebbe utilizzare cpp per ottenere una vista dell’uscita stessi, usando una stupida trigr.c programma:

    void main(){ const char *s = "??!??!"; } 

    e di lavorazione con:

    cpp -trigraphs trigr.c 

    Si otterrà una console uscita di

    void main(){ const char *s = "||"; }

    Come si può notare, l’opzione -trigraphs deve essere specificato o altro cpp emetterà un avviso; questo indica come trigrammi sono una cosa del passato e non moderna valore diverso da quello di confondere la gente che potrebbe imbattersi in loro.


    Come per la logica che sta dietro l’introduzione di trigrammi, si comprende meglio quando guardando la sezione di storia della ISO/IEC 646:

    ISO/IEC 646 e il suo predecessore ASCII (ANSI X3.4) ha approvato in larga misura la prassi esistente in materia di codifiche di caratteri nel settore delle telecomunicazioni.

    Come ASCII non ha fornito un numero di caratteri necessari per le lingue diverse dall’inglese, un certo numero di varianti nazionali, sono sostituiti alcuni dei caratteri utilizzati con quelli.

    (corsivo mio)

    Quindi, in sostanza, il bisogno di personaggi (quelli per i quali un trigramma esiste) sono stati sostituiti in alcune varianti nazionali. Questo porta alla rappresentazione alternativa utilizzando trigrammi costituiti da caratteri che altre varianti ancora aveva intorno.

Lascia un commento