c++ from Strumento per trovare cast in stile C.




extern c (8)

Il compilatore Offload C ++ supporta le opzioni per riportare come errore di compilazione tutti questi casts e per restringere la semantica di tali cast ad un'equivalenza più sicura con static_cast.

Le opzioni rilevanti sono:

-cp_nocstylecasts   

Il compilatore genererà un errore su tutti i cast in stile C. I cast in stile C nel codice C ++ possono essere potenzialmente non sicuri e portare a comportamenti indesiderati o indefiniti (ad esempio, puntatori di cast verso tipi di struttura / classe non collegati). Questa opzione è utile per il refactoring per trovare tutti quei cast e sostituirli con cast C ++ più sicuri come static_cast.

-cp_c2staticcasts   

Il compilatore applica la semantica più ristretta di C ++ static_cast ai cast di tipo C. La compilazione del codice con questa opzione attivata assicura che i cast in stile C siano almeno altrettanto sicuri dei c ++ static_casts

Questa opzione è utile se il codice esistente ha un gran numero di cast in stile C e il refactoring di ogni cast in cast di C ++ sarebbe troppo impegnativo.

Qualcuno sa di uno strumento che posso usare per trovare cast espliciti in stile C nel codice? Sto rifattorizzando un codice C ++ e voglio sostituire i cast in stile C laddove possibile.

Un cast di tipo C di esempio potrebbe essere:

Foo foo = (Foo) bar;

In contrasto esempi di cast di stile C ++ sarebbero:

Foo foo = static_cast<Foo>(bar);
Foo foo = reinterpret_cast<Foo>(bar);
Foo foo = const_cast<Foo>(bar);

Se si utilizza una sorta di notazione in stile ungherese (ad esempio iInteger , pPointer ecc.), È possibile cercare eg )p e ) p e così via.

Dovrebbe essere possibile trovare tutti quei posti in tempi ragionevoli anche per una grande base di codice.


Un problema con i cast in stile C è che, poiché si basano su parentesi che sono sovraccariche, non sono banali da individuare. Ancora, un'espressione regolare come (ad es. Nella sintassi Python):

r'\(\s*\w+\s*\)'

è un inizio - corrisponde a un singolo identificatore tra parentesi con spazi bianchi facoltativi all'interno delle parentesi. Ma ovviamente questo non colpirà, ad esempio, (void*) cast - per ottenere anche degli asterischi finali,

r'\(\s*\w+[\s*]*\)'

Puoi anche iniziare con un const opzionale per ampliare ulteriormente la rete, ecc, ecc.

Una volta che hai una buona RE, molti strumenti (da grep a vim , da awk a sed , più perl , python , ruby , ecc) ti permettono di applicarlo per identificare tutte le sue corrispondenze nella tua fonte.


Se stai usando gcc / g ++, abilita semplicemente un avviso per i cast in stile C:

g++ -Wold-style-cast ...

Ho usato questa espressione regolare in Visual Studio (2010) Trova nella casella di ricerca dei file :i\):i

Grazie a Sth per l'ispirazione (il suo post )


Ho già risposto una volta con una descrizione di uno strumento che troverà e cambierà tutti i cast se lo si desidera.

Se tutto ciò che si vuole fare è trovare tali lanci, c'è un altro strumento che lo farà facilmente, ed in effetti è l'estrema generalizzazione di tutti i suggerimenti di "espressione regolare" fatti qui. Questo è il motore di ricerca del codice sorgente SD . Questo strumento consente di cercare grandi basi di codice in termini di elementi linguistici che compongono ciascuna lingua. Fornisce una GUI che consente di inserire le domande, vedere singoli colpi e mostrare il testo del file nel punto colpito con un clic del mouse. Ancora un clic e puoi essere nel tuo editor [per molti editor] su un file. Lo strumento registrerà anche un elenco di hit nel contesto in modo da poterli rivisitare in seguito.

Nel tuo caso, è probabile che la seguente query del motore di ricerca ottenga la maggior parte dei cast:

'(' I ')'  | '(' I ... '*' ')'

il che significa trovare una sequenza di token, in primo luogo (, il secondo è un identificatore, il terzo è ")" o una sequenza simile che coinvolge qualcosa che termina con "*".

Non si specifica alcuna gestione degli spazi bianchi, in quanto lo strumento comprende le regole dello spazio bianco della lingua; ignorerà persino un commento nel mezzo di un cast e continuerà a corrispondere a quanto sopra.

[Sono il CTO della compagnia che fornisce questo.]


Il fatto che tali lanci siano così difficili da cercare è uno dei motivi per cui i cast di stile nuovo sono stati introdotti in primo luogo. E se il tuo codice funziona, sembra un po 'inutile refactoring - li cambierei semplicemente in cast di nuovo stile ogni volta che ho modificato il codice circostante.

Detto questo, il fatto di avere cast in stile C nel codice C ++ indicherebbe problemi con il codice che dovrebbe essere risolto - non farei solo una sostituzione globale, anche se fosse possibile.


La ricerca dell'espressione regolare \)\w fornisce risultati sorprendentemente buoni.





c