C / C ++ numero di riga
-
27-09-2019 - |
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)
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.