web-dev-qa-db-fra.com

Numéro de ligne C / C ++

À 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)
98
Betamoo

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__);
162
Julien Hoarau

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__);
61
Brian R. Bondy

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!

18

Utilisation __LINE__ (double soulignement LIGNE double soulignement), le préprocesseur le remplace par le numéro de ligne sur lequel il est rencontré.

11
meagar

Check-out __FILE__ et __LINE__ macros

9
Anton

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.

4
Sanctus2099

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.

1
John Doe