C / C ++ número de línea
-
27-09-2019 - |
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)
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.