Número da linha C/C++
-
27-09-2019 - |
Pergunta
Para fins de depuração, posso obter o número da linha em CCompiladores /C++?(forma padrão ou formas específicas para determinados compiladores)
por exemplo
if(!Logical)
printf("Not logical value at line number %d \n",LineNumber);
// How to get LineNumber without writing it by my hand?(dynamic compilation)
Solução
Você deve usar a macro do pré-processador __LINE__
e __FILE__
.Elas são macros predefinidas e fazem parte do padrão C/C++.Durante o pré-processamento, eles são substituídos respectivamente por uma string constante contendo um inteiro representando o número da linha atual e pelo nome do arquivo atual.
Outras variáveis do pré-processador:
__func__
:nome da função (isso faz parte de Capítulo 99, nem todos os compiladores C++ suportam isso)__DATE__
:uma string no formato "Mmm dd yyyy"__TIME__
:uma string no formato "hh:mm:ss"
Seu código será:
if(!Logical)
printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);
Outras dicas
Como parte do padrão C ++, existem algumas macros predefinidas que você pode usar. A seção 16.8 do padrão C ++ define entre outras coisas, o __LINE__
macro.
__LINE__
: O número da linha da linha de origem atual (uma constante decimal).
__FILE__
: O nome presumido do arquivo de origem (uma string de caracteres literal).
__DATE__
: A data da tradução do arquivo de origem (uma string de caracteres literal ...)
__TIME__
: O tempo de tradução do arquivo de origem (uma string de caracteres literal ...)
__STDC__
: Se__STDC__
é predefinido
__cplusplus
: O nome__cplusplus
é definido para o valor 199711L ao compilar uma unidade de tradução C ++
Então, seu código seria:
if(!Logical)
printf("Not logical value at line number %d \n",__LINE__);
Você pode usar uma macro com o mesmo comportamento que printf (), exceto que também inclui informações de depuração, como nome da função, classe e número da linha:
#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)
Essas macros devem se comportar de forma idêntica a printf (), incluindo informações do tipo Java Stacktrace. Aqui está um exemplo 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!");
}
O que resulta na seguinte saída:
main (main.cpp: 11) antes do ExampleMethod () ...
Exemplemethod (main.cpp: 7) printf () sintaxe: string = foobar, int = 42
Principal (Main.CPP: 13) Sucesso!
Usar __LINE__
(Essa é a linha dupla dupla-underscore), o pré-processador o substituirá pelo número da linha no qual é encontrado.
Confira __FILE__
e __LINE__
macros
Tentar __FILE__
e __LINE__
.
Você também pode encontrar __DATE__
e __TIME__
útil.
Embora, a menos que você precise depurar um programa no lado do cliente e, portanto, precise registrar essas informações, você deve usar a depuração normal.
Como também estou enfrentando esse problema agora e não posso adicionar uma resposta a uma pergunta diferente, mas também válida, feita aqui, fornecerei uma solução de exemplo para o problema de: Obter apenas o número da linha de onde a função foi chamada no C ++ usando modelos.
Antecedentes: no C ++, pode-se usar valores inteiros não do tipo como um argumento de modelo. Isso é diferente do uso típico de tipos de dados como argumentos de modelo. Portanto, a idéia é usar esses valores inteiros para uma chamada de função.
#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;
}
Resultado:
A função foi chamada no número da linha: 0
A função foi chamada no número da linha: 16
Uma coisa a mencionar aqui é que, no padrão C ++ 11, é possível fornecer valores de modelo padrão para funções usando o modelo. Nos valores padrão pré-C ++ 11 para argumentos não do tipo, parecem funcionar apenas para argumentos de modelo de classe. Assim, em C ++ 11, não haveria necessidade de ter definições de função duplicadas como acima. Em C ++ 11, também é válido ter argumentos de modelo const char*, mas não é possível usá -los com literais como __FILE__
ou __func__
como mencionado aqui.
Portanto, no final, se você estiver usando C ++ ou C ++ 11, isso pode ser uma alternativa muito interessante do que usar o Macro's para obter a linha de chamada.