2010-04-07 16 views
24

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

Un cast esempio C-stile sarebbe:

Foo foo = (Foo) bar; 

Negli esempi di contrasto di C++ calchi stile sarebbe:

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

Che cos'è un cast in stile C? –

+1

Un tipo tra parentesi, ad es. (int) f – AshleysBrain

+1

@Bears (int) x per esempio. –

risposta

29

Se stai usando gcc/g ++, basta attivare un avvertimento per C-style cast:

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

+1 Usa lo strumento migliore e l'approccio più semplice per il lavoro ... se funziona. –

8

Il fatto che tali calchi sono così difficili da cercare è una dei motivi per cui sono stati introdotti i cast di nuovo stile. 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.

+0

Devo conformarmi alle linee guida di codifica :) – waffleman

+0

Principalmente quelle linee guida sono per il nuovo codice digitato. Il vecchio codice verrà refactored solo quando ci sono cambiamenti necessari. Ad esempio una correzione. Refactoring solo per il refactoring costa solo il tempo (e il denaro) senza alcun beneficio. – RvdK

+0

+1 risolvili quando stai lavorando/refactoring il codice circostante (e presumibilmente ritestare). –

5

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

+1

Esattamente quello che stavo pensando! http://xkcd.com/208/ – ewall

+2

Questo funziona solo se metti il ​​cast vicino alla variabile ... che DEVO DOVREI, sempre, ma non tutti lo fanno. –

0

Un problema con i cast in stile C è che, poiché si basano su parentesi che sono sovraccariche, non sono banali da individuare. Ancora, una regex come (per esempio nella sintassi Python):

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

è un inizio - corrisponde un unico identificatore tra parentesi con spazio bianco opzionale all'interno delle parentesi. Ma, naturalmente, che non prenderà, per esempio, (void*) getta - per ottenere trailing asterischi così,

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

Si potrebbe anche iniziare con un optional const di ampliare la rete ancora di più, ecc, ecc

una volta che hai un buon RE, molti strumenti (grep-vim, da awk a sed, più perl, python, ruby, ecc) consente di applicare per identificare tutte le sue partite nell'origine.

0

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

Dovrebbe essere possibile trovare tutti quei posti in tempi ragionevoli anche per un grande numero di codici.

1

Uno strumento in grado di analizzare con precisione il codice sorgente C++ ed eseguire modifiche personalizzate automatiche (ad es., La sostituzione del cast) è il DMS Software Reengineering Toolkit.

DMS ha un parser C++ completo, crea AST e tabelle di simboli e può quindi navigare nel codice per trovare in modo affidabile i cast di stile C. Usando le corrispondenze e le riscritture orientate al pattern, è possibile fornire una serie di regole per convertire tutti i cast di tale stile C negli equivalenti C++ desiderati.

Il DMS è stato utilizzato per eseguire massicci compiti di reengineering automatizzato in C++ per Boeing e General Dynamics, ciascuno con migliaia di file.

+8

È necessario chiarire in anticipo quando si collega il proprio prodotto. –

6

Il Offload C++ compiler supporta le opzioni per segnalare come errore di compilazione tutti questi tipi di cast e per limitare la semantica di tali valori a un'equivalenza più sicura con static_cast.

Le opzioni rilevanti sono:

-cp_nocstylecasts 

Il compilatore emetterà un errore su tutti in stile C getta. 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ù limitata di C++ static_cast ai cast di tipo C. Il codice di compilazione con questa opzione attivata garantisce che i cast in stile C siano almeno altrettanto sicuri di C++ static_casts

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

+0

Oh bello! Un vero parser per una volta :) –

0

ho già risposto una volta con una descrizione di uno strumento che troverà e cambiamento tutti i calchi se lo vuoi

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 SD Source Code Search Engine. 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 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, la seguente query dei motori di ricerca è probabile che per ottenere la maggior parte dei calchi:

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

che significa, trovare una sequenza di token, prima di essere (, secondo essendo qualsiasi identificatore, terzo essere ') ', o una sequenza simile che coinvolge qualcosa che termina con' * '.

Non si specifica la gestione di 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 presso la società che fornisce questo.]

-1

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

Grazie a sth per l'ispirazione (his post)

Problemi correlati