2015-04-17 6 views
10

Sto cercando un modo per rilevare o attenuare la sorgente C++ che, una volta elaborata, si espande in dimensioni enormi, in modo che GCC esaurisca la memoria.Rileva l'abuso del preprocessore C/C++ che porta a dimensioni di codice espanse enormi

codice

Esempio:

#include <iostream> 
using namespace std; 
int main() { 
    #define A30 cout << "hello world"; 
    #define A29 if (1) { A30 } else { A30 } 
    #define A28 if (0) { A29 } else { A29 } 
    // ... you get the idea ... 
    #define A1 if (1) { A2 } else { A2 } 
    #define A0 if (0) { A1 } else { A1 } 
    A0 
    return 0; 
} 

La compilazione di questo programma dovrebbe generare un enorme, sintatticamente corretto if-else albero (funziona con le versioni più piccole; dire, fino a A10); se eseguito, stampa banalmente una delle stringhe 2^30 "ciao mondo" all'interno di quell'albero. Tuttavia, il tentativo di compilazione su una macchina da 8 GB provoca il comportamento risponde e (dopo un po ') il seguente errore da visualizzare:

internal compiler error: Segmentation fault 
A0 
^ 

È possibile limitare l'espansione pre-processore nel caso di cui sopra utilizzando GCC 4.9.x, o per evitare altrimenti di schiantarsi con tali programmi?

+7

Mentre intrigante, hai trovato un esempio reale di questo in realtà è un problema? Mi sento come se i tuoi macro fossero così contorti che stai facendo qualcosa di sbagliato altrove ... – Qix

+0

@Qix non l'hanno testato contro i compilatori online (ad es .: concorsi di programmazione), ma ho motivo di pensare che possa interessare alcuni; Suppongo di non essere il primo a pensarla, e un po 'di barba grigia C conoscerà un oscuro flag GCC per fermarlo sulle sue tracce. – tucuxi

+0

Voglio dire c'è un _real world program_ che sta generando un codice così intenso che questo sia veramente un problema? – Qix

risposta

1

Per quanto ne so non c'è modo di fare ciò che si sta cercando di ottenere con un semplice comando gcc. Un modo per aggirarlo potrebbe anche aggiungere alcuni passaggi aggiuntivi nel sistema di generazione, per vedere se un commit ha aumentato il codice base di una certa percentuale.

È disponibile un'opzione (-E) in gcc che emette il codice dopo il passaggio del pre-processore.

Se si dispone di una build su commit 1, è possibile salvare il numero di righe su quel commit, eseguire gcc con -E e fare un "wc -l" sul proprio output.

A commettere 2, prima di costruire, di fare lo stesso, e verificare che il numero di righe non è aumentato da una soglia che è stato definito (10%, 20%?)

+0

Credo che questa (e la risposta di @ POTEMKINDX usando ulimit e VS pragmas) siano gli unici approcci praticabili, anche se non sono solo gcc. Accetterò questa risposta se non accadrà nulla di meglio entro i prossimi giorni. – tucuxi