2015-05-10 15 views
9

voglio forzare le stringhe da assegnare in variabili locali dinamicamente a run-time tramite istruzioni di montaggio senza la stringa occupa di memoria in una sezione di dati (come ad esempio l'unica sezione dati lettura).C++ gcc stringa inlining

Quanto segue sembra funzionare perfettamente:

char foo[] = "bar"; 

Il codice assembly diventa:

movl $7496034, 40(%esp) 

Così, foo viene inizializzato con "bar" tramite l'istruzione movl in fase di esecuzione.

Come posso forzarlo a verificarsi su tutte le operazioni di stringa?

Ad esempio, se mi passa una stringa letterale in una funzione:

testfunc("bar"); 

La stringa "bar" saranno destinati in una sezione in questo caso.

+1

'char foo [] =" bar "; testfunc (foo); 'non funziona? –

+7

Sono curioso di sapere come funziona. –

+0

@Andrew: questo mi costringerà a dichiarare una variabile ogni volta che è ciò che sto cercando di evitare. – user3575889

risposta

5

La tecnica che mostri funziona solo per il tuo caso speciale. In generale, il compilatore è libero di inserire il contenuto delle stringhe nella sezione. Ad esempio, con questo piccolo ritocco:

char foo[] = "bar\0"; 

La stringa verrà ora visualizzata nella sezione di dati di sola lettura.

Sapendo che la tecnica non è sempre garantita, è possibile utilizzare una macro per automatizzare la tecnica in modo che sia possibile passare le stringhe alle funzioni senza utilizzare i puntatori nella sezione di sola lettura.

#define string_invoke(Func, Str)  \ 
     []() -> decltype(Func(NULL)) { \ 
      char foo[] = Str;   \ 
      return Func(foo);   \ 
     }() 
+0

Che tipo di "sezione" pensi che l'op stia parlando? –

+0

@ DOUGLASO.MOEN: Probabilmente la sezione 'rodata', se ELF. Il compilatore ha un'ottimizzazione per trasformare stringhe in valori letterali numerici e inizializzarsi di conseguenza. Stavo illustrando che l'ottimizzazione non sempre avviene, e l'inizializzazione è una 'memcpy' dal' rodata'. – jxh

3

Hai una stringa di quattro caratteri che si desidera inizializzare con quattro personaggi ("bar", più il nulla-terminatore.) Il compilatore riconosce l'occasione per un impressionante micro-ottimizzazione e salva un intero quattro byte nella stringa che ha lo stesso schema di bit di "barra". Su macchine a 64 bit, il compilatore potrebbe usare questa tecnica anche per stringhe di 8 caratteri. Meraviglioso! Ma non aspettarti che questa ottimizzazione sia applicabile ovunque tu usi le stringhe C.

Quando una funzione accetta una stringa C come parametro, ad esempio, è in attesa di un puntatore a un array, non a un intero.

Contortare il codice per forzare specifiche ottimizzazioni del compilatore è un ottimo modo per scrivere codice non gestibile e fragile. Stai meglio scrivendo codice chiaro usando algoritmi efficienti e godendo delle fantastiche ottimizzazioni che il compilatore può applicare.

+0

Bella spiegazione del motivo per cui tale ottimizzazione del lato del programmatore inutile dovrebbe essere evitata. – g24l

+2

Mi dispiace, ma non è una risposta autorevole. Dici "potrebbe" e non citi fonte. Quello che stiamo cercando è la spiegazione di quel comportamento GCC, che lo scatena. –

+0

Non sto cercando di essere autorevole. Ho detto che il GCC "potrebbe" usare la stessa ottimizzazione perché è teoricamente possibile, ma non ho verificato né mi interessa. Ho spiegato il comportamento del GCC e poi ho detto che non forzare il tuo stile di codifica per provare a invocare questa ottimizzazione. – RichN