À des fins de débogage, puis-je obtenir le numéro de ligne dans C /compilateurs C++? (manière standard ou spécifique 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)
Vous devez utiliser la macro de préprocesseur __LINE__
et __FILE__
. Ce sont des macros prédéfinies qui font partie de la norme C/C++. Lors du prétraitement, ils sont remplacés respectivement par une chaîne constante contenant un entier représentant le numéro de la ligne en cours et par le nom du fichier en cours.
Autres variables du préprocesseur:
__func__
: nom de la fonction (cela fait partie de C99 , tous les compilateurs C++ ne le prennent pas en charge)__DATE__
: une chaîne de forme "Mmm dd yyyy"__TIME__
: une chaîne de forme "hh: mm: ss"Votre code sera:
if(!Logical)
printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);
Dans le cadre de la norme C++, il existe des macros prédéfinies que vous pouvez utiliser. La section 16.8 de la norme C++ définit, entre autres, le __LINE__
macro.
__LINE__
: Le numéro de la ligne source actuelle (constante décimale).__FILE__
: Nom présumé du fichier source (littéral de chaîne de caractères).__DATE__
: La date de traduction du fichier source (une chaîne de caractères littérale ...)__TIME__
: Le temps de traduction du fichier source (une chaîne de caractères littérale ...)__STDC__
: Si__STDC__
est prédéfini__cplusplus
: Le nom__cplusplus
est défini à la valeur 199711L lors de la compilation d'une unité de traduction C++
Donc, votre code serait:
if(!Logical)
printf("Not logical value at line number %d \n",__LINE__);
Vous pouvez utiliser une macro ayant le même comportement que printf (), sauf qu'elle inclut également des informations de débogage telles que le 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 doivent se comporter de manière identique à printf (), tout en incluant Java des informations de type stacktrace. 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!");
}
Ce qui donne le résultat suivant:
main (main.cpp: 11) Avant exampleMethod () ...
exampleMethod (main.cpp: 7) syntaxe printf (): string = foobar, int = 42
main (main.cpp: 13) Succès!
Utilisation __LINE__
(double soulignement LIGNE double soulignement), le préprocesseur le remplace par le numéro de ligne sur lequel il est rencontré.
Check-out __FILE__
et __LINE__
macros
Essayez __FILE__
et __LINE__
.
Vous pourriez aussi trouver __DATE__
et __TIME__
utile.
Bien que vous deviez utiliser le débogage normal, à moins que vous ne deviez déboguer un programme du côté client et donc enregistrer ces informations.
Puisque je suis également confronté à ce problème maintenant et que je ne peux pas ajouter de réponse à une question différente, mais également valide, posée ici , je vais vous donner un exemple de solution au problème suivant: obtenir uniquement le numéro de ligne de où la fonction a été appelée en C++ à l'aide de modèles.
Fond: en C++, vous pouvez utiliser des valeurs entières non-types comme argument de modèle. Cela diffère de l'utilisation typique des types de données en tant qu'arguments de modèle. L'idée est donc d'utiliser de telles 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 au numéro de ligne: 0
la fonction a été appelée au numéro de ligne: 16
Une chose à mentionner ici est que dans C++ 11 Standard, il est possible de donner des valeurs de modèle par défaut pour les fonctions utilisant modèle. Dans les versions antérieures à C++ 11, les valeurs par défaut pour les arguments non-types ne semblaient fonctionner que pour les arguments de modèle de classe. Ainsi, en C++ 11, il ne serait pas nécessaire d'avoir des définitions de fonctions en double comme ci-dessus. En C++ 11, il est également valide d’avoir des arguments const char * template mais il n’est pas possible de les utiliser avec des littéraux tels que __FILE__
ou __func__
comme mentionné ici .
Donc, en fin de compte, si vous utilisez C++ ou C++ 11, cela pourrait être une alternative très intéressante que d’utiliser une macro pour obtenir la ligne d’appel.