Come ottenere la lunghezza di una funzione in byte?

Voglio conoscere la lunghezza della funzione C (scritta da me) in fase di esecuzione. Qualche metodo per averlo? Sembra che sizeof non funzioni qui.

Non c’è modo in C standard per ottenere la quantità di memoria occupata da una funzione.

C’è un modo per determinare la dimensione di una funzione. Il comando è:

nm -S  

Ciò restituirà le dimensioni di ogni funzione all’interno del file object. Consulta le pagine del manuale in GNU usando ‘man nm’ per raccogliere maggiori informazioni al riguardo.

È ansible ottenere queste informazioni dal linker se si utilizza uno script linker personalizzato. Aggiungi una sezione linker solo per la funzione data, con simboli linker su entrambi i lati:

 mysec_start = .; *(.mysection) mysec_end = .; 

Quindi è ansible assegnare specificamente la funzione a quella sezione. La differenza tra i simboli è la lunghezza della funzione:

 #include  int i; __attribute__((noinline, section(".mysection"))) void test_func (void) { i++; } int main (void) { extern unsigned char mysec_start[]; extern unsigned char mysec_end[]; printf ("Func len: %lu\n", mysec_end - mysec_start); test_func (); return 0; } 

Questo esempio è per GCC, ma qualsiasi toolchain C dovrebbe avere un modo per specificare a quale sezione assegnare una funzione. Vorrei verificare i risultati confrontandoli con l’elenco degli assembly per verificare che funzioni nel modo che preferisci.

Eseguibili (almeno quelli che hanno informazioni di debug rimosse) non memorizzano le lunghezze di funzione in alcun modo. Quindi non c’è la possibilità di analizzare queste informazioni in autonomia da solo. Se devi manipolare le funzioni, dovresti fare qualcosa con i tuoi oggetti nella fase di collegamento o accedendoli come file dal tuo eseguibile. Ad esempio, è ansible indicare al linker di colbind le tabelle dei simboli come sezione di dati ordinaria nell’eseguibile, assegnare loro un nome e analizzare quando viene eseguito il programma. Ma ricorda, questo sarebbe specifico per il tuo linker e il formato dell’object.

Si noti inoltre che il layout di funzione è anche specifico per la piattaforma e ci sono alcune cose che rendono poco chiaro il termine “lunghezza della funzione”:

  1. È ansible che le funzioni memorizzino le costanti utilizzate nelle sezioni di codice direttamente dopo il codice funzione e le accedano tramite l’indirizzamento relativo del PC (i compilatori ARM lo fanno).
  2. Le funzioni possono avere “prolog” e “epilog”, che possono essere comuni a diverse funzioni e quindi trovarsi al di fuori del corpo principale.
  3. Il codice funzione può incorporare un altro codice funzione

Tutti possono contare o non contare nella durata della funzione.

Anche la funzione può essere completamente delineata dal compilatore, quindi perde il suo corpo.

Ad esempio, in Codewarrior, puoi posizionare etichette attorno a una funzione, ad es

 label1: void someFunc() { /* code goes here. */ } label2: 

e quindi calcolare la dimensione come (int)(label2-label1) , ma questo è ovviamente molto dipendente dal compilatore. A seconda del sistema e del compilatore, potrebbe essere necessario modificare gli script del linker, ecc.

L’inizio della funzione è il puntatore della funzione, lo sai già.

Il problema è trovare la fine, ma ciò può essere fatto in questo modo:

 #include  int foo(void) { int i = 0; ++i + time(0); // time(0) is to prevent optimizer from just doing: return 1; return i; } int main(int argc, char *argv[]) { return (int)((long)main - (long)foo); } 

Funziona qui perché il programma ha SOLO DUE funzioni, quindi se il codice viene riordinato (implementato prima di prima), otterrai un calcolo irrilevante (negativo), facendoti sapere che non funzionava in questo modo ma che avrebbe funzionato se sposti il ​​codice foo () in main () – sottrai solo la dimensione main () che hai ottenuto con la risposta negativa iniziale.

Se il risultato è positivo, allora sarà corretto -se non viene eseguito alcun riempimento (sì, alcuni compilatori gonfiano felicemente il codice, sia per l’allineamento che per altri motivi meno ovvi).

Il cast finale (int) (long) è per la portabilità tra codice a 32 bit e a 64 bit (i puntatori di funzione saranno più lunghi su una piattaforma a 64 bit).

Questo è faily portatile e dovrebbe funzionare abbastanza bene.

Basta sottrarre l’indirizzo della tua funzione dall’indirizzo della funzione successiva. Nota che potrebbe non funzionare sul tuo sistema, quindi usalo solo se sei sicuro al 100%:

 #include  int function() { return 0; } int function_end() { return 0; } int main(void) { intptr_t size = (intptr_t) function_end - (intptr_t) function; } 

Non esiste una funzione definita all’interno del linguaggio C per restituire la lunghezza di una funzione; ci sono semplicemente troppe variabili coinvolte (compilatore, set di istruzioni di destinazione, file object / formato file eseguibile, impostazioni di ottimizzazione, impostazioni di debug, ecc.). Lo stesso codice sorgente può comportare funzioni di dimensioni diverse per sistemi diversi.

C semplicemente non fornisce alcun tipo di capacità di riflessione per supportare questo tipo di informazioni (sebbene singoli compilatori possano fornire estensioni, come l’esempio Codewarrior citato da sskuce). Se hai bisogno di sapere quanti byte occupa la tua funzione in memoria, dovrai esaminare direttamente l’object generato o il file eseguibile.

sizeof func non funzionerà perché l’espressione func viene trattata come un puntatore alla funzione, quindi ottieni la dimensione del valore di un puntatore, non la funzione stessa.

Non esiste un modo standard per farlo in C o C ++. Ci potrebbero naturalmente esistere modalità di implementazione / piattaforma specifiche per farlo, ma non ne sono a conoscenza

Puoi trovare la lunghezza della tua funzione C sottraendo gli indirizzi delle funzioni. Lascia che ti fornisca un esempio

 int function1() { } int function2() { int a,b; //just defining some variable for increasing the memory size printf("This function would take more memory than earlier function ie function01 "); } int main() { printf("Printing the address of function01 %p\n",function01); printf("Printing the address of function02 %p\n",function02); printf("Printing the address of main %p\n",main); return 0; } 

Spero che otterresti la tua risposta dopo averla compilata. Dopo la compilazione potrai vedere la differenza di dimensioni di function01 e function2.

Nota: normalmente c’è una differenza di 16bytes tra una funzione e l’altra.