Pregunta

En aras de fines de depuración, puedo obtener el número de línea en C ++ / compiladores de C? (Forma o específicas formas estándar para ciertos compiladores)

por ejemplo

if(!Logical)
    printf("Not logical value at line number %d \n",LineNumber);
    // How to get LineNumber without writing it by my hand?(dynamic compilation)
¿Fue útil?

Solución

Se debe utilizar el preprocesador macro __LINE__ y __FILE__. Ellos están predefinidas macros y parte de la norma C / C ++. Durante el procesamiento previo, que se sustituyen, respectivamente, por una constante de cadena que sostiene un entero que representa el número de línea actual y por el nombre de archivo actual.

Otros preprocesador variables:

  • __func__: nombre de la función (esto es parte de C99 , no todos los compiladores de C ++ soporta)
  • __DATE__: una cadena de la forma "MMM DD AAAA"
  • __TIME__: una cadena de la forma "hh: mm: ss"

Su código será:

if(!Logical)
  printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);

Otros consejos

Como parte del C ++ estándar no existe algunas macros predefinidas que se pueden utilizar. Sección 16.8 de la C ++ norma define entre otras cosas, la macro __LINE__.

  

__LINE__: El número de línea de la línea de fuente de corriente (un decimal   constante).
   __FILE__: El presunto nombre del archivo de origen (una cadena de caracteres   literal).
   __DATE__: La fecha de la traducción del archivo de origen (una cadena de caracteres   literal ...)
   __TIME__: La hora de la traducción del archivo de origen (una cadena de caracteres   literal ...)
   __STDC__: Whether__STDC__ está predefinido
   __cplusplus: El nombre __cplusplus se define para la 199711L valor cuando   la compilación de una unidad de C ++ traducción

Así que el código sería:

if(!Logical)
  printf("Not logical value at line number %d \n",__LINE__);

Se puede usar un macro con el mismo comportamiento que printf () , excepto que también incluye información de depuración como nombre de la función, clase y número de línea:

#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)

Estas macros debe comportarse de forma idéntica a printf () , mientras incluyendo Java StackTrace-como información. He aquí un ejemplo 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!");
}

Lo cual da como resultado el siguiente resultado:

  

principal (main.cpp: 11) Antes de ExampleMethod () ...
  ExampleMethod (main.cpp: 7) printf () Sintaxis: String = foobar, int = 42
  principal (main.cpp: 13) El éxito!

Uso __LINE__ (que es de doble subrayado LÍNEA doble subrayado), el preprocesador lo reemplazará por el número de líneas en que se encuentra.

Pedido __FILE__ y __LINE__ macros

Trate __FILE__ y __LINE__.
También puede encontrar __DATE__ y __TIME__ útil.
Aunque menos que sea necesario depurar un programa en el del lado del cliente y por lo tanto es necesario registrar estas informaciones que debe utilizar la depuración normal.

Debido a que también estoy frente a este problema ahora y no puedo añadir una respuesta a un aquí , Voy a ofrecer una solución para el problema de ejemplo de: recibiendo sólo el número de línea donde la función ha sido llamada en C ++ usando plantillas.

Antecedentes: en C ++ se puede utilizar valores enteros no de tipo como un argumento de plantilla. Esto es diferente que el uso típico de los tipos de datos como argumentos de plantilla. Así que la idea es utilizar este tipo de valores enteros para una llamada de función.

#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;
}

Salida:

  

la función que se ha llamado en la línea número: 0

     

la función que se ha llamado en la línea número: 16

Una cosa a mencionar aquí es que en C ++ 11 estándar que es posible dar valores de la plantilla por defecto para las funciones utilizando la plantilla. En C ++ 11 pre valores por defecto de los argumentos no parecen tipo único trabajo de argumentos de plantilla de clase. Así, en C ++ 11, no habría necesidad de tener definiciones de funciones duplicadas como anteriormente. En C ++ 11 su también válido para tener const char * argumentos de plantilla, pero no es posible utilizarlos con literales como __FILE__ o __func__ como se mencionó aquí .

Así que al final, si usted está usando C ++ o C ++ 11 Esto podría ser una alternativa muy interesante que el uso de macros para obtener la línea de llamada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top