Dans un souci de débogage, puis-je obtenir le numéro de ligne dans les compilateurs C / C ++? (méthode standard ou méthodes 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)
Réponses:
Vous devez utiliser la macro de préprocesseur
__LINE__
et__FILE__
. Ce sont des macros prédéfinies et une 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 ligne courant et par le nom du fichier courant.Autres variables de 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 la forme "Mmm jj aaaa"__TIME__
: une chaîne de forme "hh: mm: ss"Votre code sera:
la source
#define S1(N) #N
#define S2(N) S1(N)
#define LINESTR S2(__LINE__)
. Voir c-faq.com/ansi/stringize.html__func__
n'est pas une macro, c'est une variable implicitement déclarée.Dans le cadre de la norme C ++, il existe des macros prédéfinies que vous pouvez utiliser. La section 16.8 du standard C ++ définit entre autres la
__LINE__
macro.Donc, votre code serait:
la source
Vous pouvez utiliser une macro avec 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:
Ces macros doivent se comporter de la même manière que printf () , tout en incluant des informations de type java stacktrace. Voici un exemple principal:
Ce qui entraîne la sortie suivante:
la source
#include
<stdio.h>
Utilisez
__LINE__
(c'est un double trait de soulignement LINE double-underscore), le préprocesseur le remplacera par le numéro de ligne sur lequel il est rencontré.la source
Paiement
__FILE__
et__LINE__
macrosla source
C ++ 20 offre une nouvelle façon d'y parvenir en utilisant std :: source_location . Ceci est actuellement accessible dans gcc an clang comme
std::experimental::source_location
avec#include <experimental/source_location>
.Le problème avec des macros comme
__LINE__
c'est que si vous voulez créer par exemple une fonction de journalisation qui affiche le numéro de ligne actuel avec un message, vous devez toujours passer en__LINE__
tant qu'argument de fonction, car il est développé sur le site d'appel. Quelque chose comme ça:Affiche toujours la ligne de la déclaration de fonction et non la ligne d'où a
log
été réellement appelée. D'un autre côté, avecstd::source_location
vous pouvez écrire quelque chose comme ceci:Ici,
loc
est initialisé avec le numéro de ligne pointant vers l'emplacement où alog
été appelé. Vous pouvez l'essayer en ligne ici.la source
Essayez
__FILE__
et__LINE__
.Vous pourriez également trouver
__DATE__
et__TIME__
utile.Cependant, à moins que vous n'ayez à déboguer un programme côté client et que vous ayez donc besoin de consigner ces informations, vous devriez utiliser le débogage normal.
la source
raw code
(comme ceci: `__`). @mmyers a tenté d'aider, mais il n'a échappé qu'à l'un des traits de soulignement, et il vous restait donc la syntaxe de balisage pour l' italique . Les votes négatifs sont un peu durs ici, cependant, je suis d'accord.Pour ceux qui pourraient en avoir besoin, une macro "FILE_LINE" pour imprimer facilement fichier et ligne:
la source
Étant donné que 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 fournir un exemple de solution pour le problème de: obtenir uniquement le numéro de ligne où la fonction a été appelée C ++ à l'aide de modèles.
Contexte: en C ++, on peut utiliser des valeurs entières non de type comme 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 de telles valeurs entières pour un appel de fonction.
Production:
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 un modèle. Dans la version antérieure à C ++ 11, les valeurs par défaut des arguments non de type semblent fonctionner uniquement pour les arguments de modèle de classe. Ainsi, dans C ++ 11, il n'y aurait pas besoin d'avoir des définitions de fonction en double comme ci-dessus. En C ++ 11, il est également valide d'avoir des arguments de modèle const char *, mais il n'est pas possible de les utiliser avec des littéraux comme
__FILE__
ou__func__
comme mentionné ici .Donc, à la fin, si vous utilisez C ++ ou C ++ 11, cela pourrait être une alternative très intéressante que d'utiliser des macros pour obtenir la ligne d'appel.
la source
Utilisation
__LINE__
, mais quel est son type?En tant que constante entière , le code peut souvent supposer que la valeur est
__LINE__ <= INT_MAX
et donc le type estint
.Pour imprimer en C, a
printf()
besoin du prescripteur correspondant:"%d"
. C'est une préoccupation bien moindre en C ++ aveccout
.Inquiétude pédante: si le numéro de ligne dépasse
INT_MAX
1 (quelque peu concevable avec 16 bitsint
), espérons que le compilateur produira un avertissement. Exemple:Sinon, le code pourrait forcer des types plus larges à prévenir de tels avertissements.
Éviter
printf()
Pour éviter toutes les limitations d'entiers: stringify . Le code pourrait s'imprimer directement sans
printf()
appel: une bonne chose à éviter dans la gestion des erreurs 2 .1 Pratique de programmation certainement médiocre pour avoir un fichier aussi volumineux, mais peut-être que le code généré par la machine peut devenir élevé.
2 Lors du débogage, il arrive que le code ne fonctionne tout simplement pas comme prévu. L'appel de fonctions complexes comme
*printf()
peut entraîner des problèmes par rapport à un simplefputs()
.la source