2013-07-18 16 views
21

Sto refactoring del codice molto vecchio che è pieno di bug e pratiche molto discutibili, almeno per gli standard moderni. Ora mi sono imbattuto in una linea che io semplicemente non riesco a decifrare:Linea criptica "??! ??!" nel codice precedente

p e k sono di tipo int *

return p??!??!k?p?*p:sizeof(*k):0; 

Quando l'ho visto non potevo credere ai miei occhi - So che l'operatore ?, ma la sua sintassi è bool ? trueresult : falseresult e un operatore ?? non ha alcun senso (la valutazione lazy in realtà non si applica qui), non potrei trovare un riferimento di quel misterioso operatore da nessuna parte.

Sarebbe davvero bello se qualcuno chiarisse la questione.

+2

http://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C – qrdl

+0

quale compilatore stai usando ? gcc, ad esempio, ignora i trigraph di default. E sì, questo deve essere * codice molto, molto vecchio *, infatti. – devnull

+0

@devnull È gcc ma è compilato con un Makefile. E ora che so cosa sono i trigraph so anche perché c'è un flag '-trigraphs' passato al compilatore;) – user2573221

risposta

37

Si chiama Trigraph:

C11 (ISO/IEC 9899: 201x) §5.2.1.1 Trigraph sequenze

Prima di qualsiasi altra elaborazione ha luogo, ogni occorrenza di uno dei seguenti sequenze di tre caratteri (chiamate sequenze trigraph17)) viene sostituito con il carattere singolo corrispondente .

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

E 'anche in C++ 11 (ISO/IEC 14882: 2011) § 2.3 sequenze trigraph

Così, dopo la sostituzione trigraph, la linea return p??!??!k?p?*p:sizeof(*k):0; si trasforma in

return p || k ? p ? *p : sizeof(*k) : 0 

Poiché l'operatore ternario ha una precedenza piuttosto bassa, in realtà è:

return (p || k) ? (p ? (*p) : sizeof(*k)) : 0; 
6

Quella riga di codice è equivalente a:

return p || k? p? *p : sizeof(*k) : 0; 

O più chiaramente:

return (p || k)? (p? (*p) : sizeof(*k)) : 0; 
Problemi correlati