В целях отладки, могу ли я получить номер строки в C/С++ компиляторах?
(стандартный способ или конкретные способы для определенных компиляторов)
например
if(!Logical)
printf("Not logical value at line number %d \n",LineNumber);
// How to get LineNumber without writing it by my hand?(dynamic compilation)
Ответ 1
Вы должны использовать макрос препроцессора __LINE__
и __FILE__
. Это предопределенные макросы и часть стандарта C/С++. Во время предварительной обработки они заменяются соответственно константной строкой, содержащей целое число, представляющее текущий номер строки и текущее имя файла.
Другие препроцессорные переменные:
-
__func__
: имя функции (это часть C99, не все компиляторы С++ поддерживают ее)
-
__DATE__
: строка формы "Mmm dd yyyy"
-
__TIME__
: строка формы "hh: mm: ss"
Ваш код будет:
if(!Logical)
printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);
Ответ 2
Как часть стандарта С++ существуют определенные предопределенные макросы, которые вы можете использовать. Раздел 16.8 стандарта С++ определяет, помимо прочего, макрос __LINE__
.
__LINE__
: Номер строки текущей строки источника (десятичная константа).
__FILE__
: Предполагаемое имя исходного файла (символьная строка дословный).
__DATE__
: Дата перевода исходного файла (символьная строка Буквальный...)
__TIME__
: Время перевода исходного файла (символьная строка Буквальный...)
__STDC__
: Предоставляется ли __STDC__
__cplusplus
: Имя __cplusplus
определяется значением 199711L, когда компиляция единицы перевода С++
Таким образом, ваш код будет выглядеть следующим образом:
if(!Logical)
printf("Not logical value at line number %d \n",__LINE__);
Ответ 3
Вы можете использовать макрос с тем же поведением, что и printf(),
за исключением того, что он также включает в себя отладочную информацию, такую как
имя функции, класс и номер строки:
#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)
Эти макросы должны вести себя одинаково с printf(), включая информацию о java stacktrace. Вот пример main:
void exampleMethod() {
println("printf() syntax: string = %s, int = %d", "foobar", 42);
}
int main(int argc, char** argv) {
print("Before exampleMethod()...\n");
exampleMethod();
println("Success!");
}
В результате получается следующий результат:
main (main.cpp: 11) До exampleMethod()...
exampleMethod (main.cpp: 7) printf() синтаксис: string = foobar, int = 42
main (main.cpp: 13) Успех!
Ответ 4
Используйте __LINE__
(двойное подчеркивание LINE с двойным подчеркиванием), препроцессор заменит его номером строки, с которым он встречается.
Ответ 5
Оформить заказ __FILE__
и __LINE__
макросы
Ответ 6
Попробуйте __FILE__
и __LINE__
.
Вы также можете найти __DATE__
и __TIME__
.
Хотя, если вам не нужно отлаживать программу на клиентском компьютере и, следовательно, необходимо регистрировать эту информацию, вы должны использовать обычную отладку.
Ответ 7
Так как я тоже сталкиваюсь с этой проблемой сейчас, и я не могу добавить ответ на другой, но также действительный вопрос, заданный здесь,
я приведу пример решения проблемы:
получая только номер строки, где функция была вызвана в С++ с использованием шаблонов.
Фон: на С++ в качестве аргумента шаблона можно использовать целочисленные значения не-типа. Это отличается от типичного использования типов данных в качестве аргументов шаблона.
Поэтому идея состоит в том, чтобы использовать такие целочисленные значения для вызова функции.
#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;
}
Вывод:
функция вызывается в номере строки: 0
функция вызывается в строке номера: 16
Здесь стоит упомянуть, что в С++ 11 Standard можно задать значения шаблона по умолчанию для функций с использованием шаблона. В pre С++ 11 значения по умолчанию для аргументов не-типа, похоже, работают только для аргументов шаблона шаблона. Таким образом, в С++ 11 нет необходимости иметь дублированные определения функций, как указано выше. В С++ 11 он также действителен для аргументов const char *, но их невозможно использовать с литералами типа __FILE__
или __func__
, как упоминалось здесь.
Итак, в конце, если вы используете С++ или С++ 11, это может быть очень интересной альтернативой, чем использование макроса для вызова вызывающей строки.