Número de línea C/C++
c-preprocessor line-numbers (7)
En aras de la depuración, ¿puedo obtener el número de línea en los compiladores C / C ++? (forma estándar o formas específicas para ciertos compiladores)
p.ej
if(!Logical)
printf("Not logical value at line number %d /n",LineNumber);
// How to get LineNumber without writing it by my hand?(dynamic compilation)
Como ahora también estoy enfrentando este problema y no puedo agregar una respuesta a una pregunta diferente, pero también válida, here , proporcionaré una solución de ejemplo para el problema de: obtener solo el número de línea donde se ha llamado a la función C ++ usando plantillas.
Fondo: en C ++ uno puede usar valores enteros que no sean de tipo como un argumento de plantilla. Esto es diferente al uso típico de tipos de datos como argumentos de plantilla. Entonces la idea es usar tales 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 ha sido llamada en el número de línea: 0
la función ha sido llamada en el número de línea: 16
Una cosa para mencionar aquí es que en C ++ 11 Standard es posible dar valores de plantillas predeterminadas para funciones que usan plantillas. En pre C + + 11, los valores predeterminados para los argumentos que no son de tipo parecen funcionar solo para los argumentos de la plantilla de clase. Por lo tanto, en C ++ 11, no habría necesidad de tener definiciones de funciones duplicadas como se indicó anteriormente. En C ++ 11 también es válido tener argumentos de plantilla const char * pero no es posible utilizarlos con literales como __FILE__
o __func__
como se menciona here .
Así que, al final, si está usando C ++ o C ++ 11, esta podría ser una alternativa muy interesante que utilizar macro para obtener la línea de llamada.
Como parte del estándar de C ++, existen algunas macros predefinidas que puede usar. La sección 16.8 del estándar C ++ define, entre otras cosas, la macro __LINE__
.
__LINE__
: el número de línea de la línea fuente actual (una constante decimal).
__FILE__
: el nombre presunto del archivo de origen (un literal de cadena de caracteres).
__DATE__
: la fecha de traducción del archivo fuente (literal de una cadena de caracteres ...)
__TIME__
: el momento de la traducción del archivo fuente (literal de una cadena de caracteres ...)
__STDC__
: Si__STDC__
está predefinido
__cplusplus
: el nombre__cplusplus
se define con el valor 199711L al compilar una unidad de traducción C ++
Entonces tu código sería:
if(!Logical)
printf("Not logical value at line number %d /n",__LINE__);
Debe usar la macro del preprocesador __LINE__
y __FILE__
. Son macros predefinidas y parte del estándar C / C ++. Durante el preprocesamiento, se reemplazan respectivamente por una cadena constante que contiene un número entero que representa el número de línea actual y por el nombre del archivo actual.
Otras variables de preprocesador:
-
__func__
: nombre de la función (esto es parte de C99 , no todos los compiladores de C ++ lo admiten) -
__DATE__
: una cadena de forma "Mmm dd aaaa" -
__TIME__
: una cadena de forma "hh: mm: ss"
Tu código será:
if(!Logical)
printf("Not logical value at line number %d in file %s/n", __LINE__, __FILE__);
Finalizar __FILE__
y __LINE__
macros
Pruebe __FILE__
y __LINE__
.
También puede encontrar que __DATE__
y __TIME__
útiles.
Aunque, a menos que tenga que depurar un programa en el lado del cliente y, por lo tanto, necesite registrar estas informaciones, debería usar la depuración normal.
Puede usar una macro con el mismo comportamiento que printf () , excepto que también incluye información de depuración como nombre de 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 deberían comportarse de forma idéntica a printf () , al tiempo que incluyen información similar a Java stacktrace. Aquí hay 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 que resulta en el siguiente resultado:
main (main.cpp: 11) Before exampleMethod () ...
exampleMethod (main.cpp: 7) printf () sintaxis: string = foobar, int = 42
main (main.cpp: 13) ¡Éxito!
Use __LINE__
(eso es doble subrayado LINE doble guión bajo), el preprocesador lo reemplazará con el número de línea en el que se encuentra.