C / C ++ numéro de ligne
-
27-09-2019 - |
Question
Dans un souci de fins de débogage, puis-je obtenir le numéro de ligne C / C ++ compilateurs? (Façons de façon standard ou spécifiques pour certains compilateurs)
par exemple
if(!Logical)
printf("Not logical value at line number %d \n",LineNumber);
// How to get LineNumber without writing it by my hand?(dynamic compilation)
La solution
Vous devez utiliser le préprocesseur macro __LINE__
et __FILE__
. Ils sont des macros prédéfinies et une partie de la norme du C / C. Au cours de pré-traitement, ils sont remplacés respectivement par une constante chaîne tenant un nombre entier représentant le numéro de ligne et le nom du fichier en cours.
Autres préprocesseur variables
-
__func__
: nom de la fonction (ce qui fait partie de C99 , tous les compilateurs C ++ prennent en charge) -
__DATE__
: une chaîne de la forme "Mmm dd yyyy" -
__TIME__
: une chaîne de la forme "hh: mm: ss"
Votre code sera:
if(!Logical)
printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);
Autres conseils
Dans le cadre du standard C ++ il existe certaines macros prédéfinies que vous pouvez utiliser. L'article 16.8 du standard C ++ définit, entre autres, la macro __LINE__
.
__LINE__
: Le numéro de ligne de la ligne de source de courant (une décimale constante).
__FILE__
: Le nom présumé du fichier source (une chaîne de caractères littéral).
__DATE__
: La date de la traduction du fichier source (une chaîne de caractères littéral ...)
__TIME__
: Le temps de la traduction du fichier source (une chaîne de caractères littéral ...)
__STDC__
: Whether__STDC__
est prédéfini
__cplusplus
: Le nom__cplusplus
est défini à la valeur 199711L lorsque la compilation d'une unité de traduction de C ++
Alors votre code serait:
if(!Logical)
printf("Not logical value at line number %d \n",__LINE__);
Vous pouvez utiliser une macro avec le même comportement que printf () , sauf qu'il comprend également des informations de débogage telles que nom de la fonction, la classe et le numéro de ligne:
#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)
Ces macros doit se comporter de façon identique à printf () , tout en incluant stacktrace comme l'information java. Voici un exemple principal:
void exampleMethod() {
println("printf() syntax: string = %s, int = %d", "foobar", 42);
}
int main(int argc, char** argv) {
print("Before exampleMethod()...\n");
exampleMethod();
println("Success!");
}
Quels sont les résultats de la sortie suivante:
principal (main.cpp: 11) Avant exampleMethod () ...
exampleMethod (main.cpp: 7) printf () Syntaxe: string = toto, int = 42
principal (main.cpp: 13) Succès!
Utilisez __LINE__
(qui est LINE double underscore double underscore), le préprocesseur remplacera avec le numéro de la ligne sur laquelle il est rencontré.
Commander __FILE__
et __LINE__
macros
Essayez __FILE__
et __LINE__
.
Vous pouvez également trouver __DATE__
et __TIME__
utiles.
Bien moins que vous ayez à déboguer un programme sur la clientside et ont donc besoin de se connecter ces informations, vous devez utiliser le débogage normal.
Depuis que je suis également face à ce problème maintenant et je ne peux pas ajouter une réponse à une autre question, mais aussi valide a demandé ici , Je vais vous donner une exemple de solution pour le problème de: obtenir que le numéro de ligne où la fonction a été appelée en C ++ en utilisant des modèles.
Contexte: en langage C ++, on peut utiliser des valeurs entières de type non comme un argument de modèle. Ceci est différent de l'utilisation typique des types de données comme arguments de modèle. L'idée est donc d'utiliser ces valeurs entières pour un appel de fonction.
#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;
}
Sortie:
la fonction a été appelée à la ligne numéro: 0
la fonction a été appelée à la ligne numéro: 16
Une chose à mentionner ici est que, en C ++ 11 standard, il est possible de donner des valeurs de modèle par défaut pour les fonctions en utilisant le modèle. En avant C ++ 11 valeurs par défaut pour les arguments non type semblent seulement travailler pour les arguments de modèle de classe. Ainsi, en C ++ 11, il n'y aurait pas besoin d'avoir des définitions de fonction en double comme ci-dessus. En C ++ 11 est aussi valide pour avoir const char * arguments de modèle, mais ce ne est pas possible de les utiliser avec littéraux comme __FILE__
ou __func__
comme mentionné .
Donc à la fin si vous utilisez C ++ ou C ++ 11 cela pourrait être une alternative très intéressante que l'utilisation de macro pour obtenir la ligne d'appel.