2013-04-08 19 views
8

C'è un modo in C++ 11 (utilizzando l'ultimo GCC) per ottenere il nome, o il numero di file e di linea, di il metodo che chiama il metodo attualmente eseguito (il chiamante)?Come ottenere il nome, o il file e la linea del metodo del chiamante?

voglio usare queste informazioni in un messaggio di errore quando, ad esempio, il seguente codice non riesce:

void SomewhereInMyProgram() 
{ 
    DoSomething(nullptr); 
} 

void DoSomething(const char* str) 
{ 
    Contract::Requires(str != nullptr); 
    // ... 
} 

Attualmente ho il codice in luogo che segnala l'errore, come si verificano in DoSomething. Sebbene ciò sia tecnicamente vero, mi piacerebbe che segnalasse l'errore come accaduto in SomewhereInMyProgram ovunque si trovasse. Ciò renderebbe la mia vita molto più facile!

La soluzione può utilizzare qualsiasi funzionalità di C++ 11, macro o GCC, ma non qualcosa che devo aggiungere in ogni sito di chiamata.

Penso che uno stacktrace sarà non help me, perché non posso utilizzare la gestione delle eccezioni. In realtà, sono molto limitato: si tratta di un ambiente indipendente in cui le intestazioni standard di C++ non sono disponibili. Speravo in una soluzione macro di qualche tipo.


class Contract 
{ 
public: 
    static void RequiresImpl(bool condition, const char* expression, 
     const char* file, int line); 

    #define Requires(condition) RequiresImpl(condition, #condition , \ 
     __FILE__, __LINE__) 
}; 
+3

Sembra che tu stia cercando uno stacktrace di runtime, ovvero dai un'occhiata a questa domanda SO (come ottengono lo stacktrace) http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace- when-my-gcc-c-app-crashes – epatel

+0

@epatel Sono ** non ** in cerca di uno stacktrace, perché non posso usare la gestione delle eccezioni. A proposito, sicuramente non sto facendo la stessa domanda di quella che hai contrassegnato come duplicato? – Virtlink

+0

Intendevo dire che dovresti esaminare la funzione 'handler()' per vedere come ottengono la traccia dello stack da lì, cioè le funzioni 'backtrace()', 'backtrace_symbols()' e 'backtrace_symbols_fd()'. Prova a utilizzarli nello stesso posto in cui desideri ottenere il "chiamante" – epatel

risposta

1

Al meglio della mia conoscenza, l'unico modo per ottenere automaticamente le informazioni sulle chiamate precedenti è quello di utilizzare un backtrace. Questo post ha una tonnellata di informazioni circa fare quello:

How to generate a stacktrace when my gcc C++ app crashes

+0

Dopo aver letto i tuoi requisiti aggiuntivi, penso che dovrai usare qualcosa di simile: http://stackoverflow.com/questions/5081123/how- to-add-code-at-the-entry-of-every-function – krowe

5

Wrap DoSomething in una macro:

void DoSomethingImp(char const *, char const *file, char const *line) 
{ 
    // do whatever needed, use file and line to report problems 
} 

#define DoSomething(x) DoSomethingImp(x, __FILE__, __LINE__) 

NOTA BENE:

Questa non è la cosa migliore da fare, le persone stanno urlando su macro API WIN definite in questo modo per ANSI o UNICODE. Ma credo che questo sia l'unico modo se non si desidera modificare ogni chiamata a DoSomething.

-2

In gcc è possibile utilizzare una delle seguenti macro: __PRETTY_FUNCTION__ o __FUNCTION__ o __func__.

+0

Fornisce il nome della funzione corrente, non il nome o il numero di riga della funzione chiamante. – ShreevatsaR

+0

Hai ragione. Ho letto male la domanda. – Amartel

Problemi correlati