Domanda

In amore della finalità di debug, posso ottenere il numero di riga in C / C ++ compilatori? (Modo o specifici modi standard per alcuni compilatori)

es

if(!Logical)
    printf("Not logical value at line number %d \n",LineNumber);
    // How to get LineNumber without writing it by my hand?(dynamic compilation)
È stato utile?

Soluzione

Si dovrebbe utilizzare la macro __LINE__ preprocessore e __FILE__. Essi sono predefiniti macro e parte standard C / C ++. Durante preelaborazione, vengono sostituite rispettivamente da una stringa costante che tiene un intero che rappresenta il numero di riga corrente e il nome del file corrente.

Altro preprocessore variabili:

  • __func__: nome della funzione (questo fa parte di C99 , non tutti i compilatori C ++ lo supportano)
  • __DATE__: una stringa di formato "Mmm dd yyyy"
  • __TIME__: una stringa della forma "hh: mm: ss"

Il tuo codice sarà:

if(!Logical)
  printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);

Altri suggerimenti

Come parte del C ++ standard di esiste alcune macro predefiniti che è possibile utilizzare. Sezione 16.8 del C ++ definisce standard, tra le altre cose, la macro __LINE__.

  

__LINE__: Il numero di riga della linea di sorgente di corrente (decimale   costante).
   __FILE__: Il nome presunta del file di origine (una stringa di caratteri   letterale).
   __DATE__: La data di traduzione del file sorgente (una stringa di caratteri   letterale ...)
   __TIME__: Il tempo della traduzione del file di origine (una stringa di caratteri   letterale ...)
   __STDC__: Whether__STDC__ è predefinito
   __cplusplus: Il __cplusplus nome è definito al valore quando 199711L   la compilazione di un'unità di C ++ traduzione

Così il vostro codice sarebbe:

if(!Logical)
  printf("Not logical value at line number %d \n",__LINE__);

Si potrebbe utilizzare una macro con lo stesso comportamento di printf () , Solo che include anche informazioni di debug, come nome della funzione, di classe, e il numero di riga:

#include <cstdio>  //needed for printf
#define print(a, args...) printf("%s(%s:%d) " a,  __func__,__FILE__, __LINE__, ##args)
#define println(a, args...) print(a "\n", ##args)

Queste macro dovrebbe comportarsi in modo identico a printf () , mentre tra cui Java stacktrace-come le informazioni. Ecco un esempio principale:

void exampleMethod() {
    println("printf() syntax: string = %s, int = %d", "foobar", 42);
}

int main(int argc, char** argv) {
    print("Before exampleMethod()...\n");
    exampleMethod();
    println("Success!");
}

che si traduce nella seguente output:

  

principale (main.cpp: 11) Prima exampleMethod () ...
  exampleMethod (main.cpp: 7) printf () sintassi: String = foobar, int = 42
  principale (main.cpp: 13) Successo!

Usa __LINE__ (che è doppia sottolineatura LINE doppia sottolineatura), il preprocessore lo sostituirà con il numero di linee su cui si incontra.

Checkout __FILE__ e __LINE__ macro

Prova __FILE__ e __LINE__.
Si potrebbe anche trovare __DATE__ e __TIME__ utile.
Anche se non si dispone di eseguire il debug di un programma sul lato client e quindi effettuare il login queste informazioni si consiglia di utilizzare il normale debug.

Dal momento che sono anche di fronte a questo problema ora e non posso aggiungere una risposta ad una diversa, ma anche domanda valida chiesto qui , io vi fornirò una soluzione ad esempio per il problema di: ottenendo solo il numero di riga in cui la funzione è stata chiamata in C ++ utilizzando i modelli.

Fondo: in C ++ si possono utilizzare valori interi non di tipo come argomento di template. Questo è diverso dal tipico utilizzo di tipi di dati come argomenti di template. Così l'idea è quella di utilizzare tali valori interi per una chiamata di funzione.

#include <iostream>

class Test{
    public:
        template<unsigned int L>
        int test(){
            std::cout << "the function has been called at line number: " << L << std::endl;
            return 0;
        }
        int test(){ return this->test<0>(); }
};

int main(int argc, char **argv){
    Test t;
    t.test();
    t.test<__LINE__>();
    return 0;
}

Output:

  

la funzione è stata richiamata alla riga: 0

     

la funzione è stata richiamata alla riga: 16

Una cosa da ricordare è che in C ++ 11 standard è possibile fornire valori modello predefinito per le funzioni che utilizzano modello. Nel pre C ++ 11 valori di default per gli argomenti non di tipo sembrano lavorare solo per gli argomenti di modello di classe. Così, in C ++ 11, non ci sarebbe bisogno di avere definizioni di funzioni duplicate come sopra. In C ++ 11 il suo valido anche per avere const char * argomenti modello, ma la sua non è possibile utilizzarli con letterali come __FILE__ o __func__ come detto qui .

Così, alla fine, se si sta utilizzando C ++ o C ++ 11 questo potrebbe essere un'alternativa molto interessante rispetto all'utilizzo di macro per ottenere la linea chiamante.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top