Номер строки C/С++

В целях отладки, могу ли я получить номер строки в 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, это может быть очень интересной альтернативой, чем использование макроса для вызова вызывающей строки.