Могу ли я получить номер строки в компиляторах 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)
Ответы:
Вы должны использовать макрос препроцессора
__LINE__
и__FILE__
. Это предопределенные макросы и часть стандарта C / C ++. Во время предварительной обработки они заменяются соответственно постоянной строкой, содержащей целое число, представляющее текущий номер строки, и текущее имя файла.Другие переменные препроцессора:
__func__
: имя функции (это часть C99 , не все компиляторы C ++ поддерживают ее)__DATE__
: строка вида «Ммм дд гггг»__TIME__
: строка вида "чч: мм: сс"Ваш код будет:
источник
#define S1(N) #N
#define S2(N) S1(N)
#define LINESTR S2(__LINE__)
. См. C-faq.com/ansi/stringize.html__func__
это не макрос, это неявно объявленная переменная.В рамках стандарта C ++ существует несколько предопределенных макросов, которые вы можете использовать. Раздел 16.8 стандарта C ++ определяет, помимо прочего,
__LINE__
макрос.Итак, ваш код будет:
источник
Вы можете использовать макрос с тем же поведением, что и printf () , за исключением того, что он также включает отладочную информацию, такую как имя функции, класс и номер строки:
Эти макросы должны вести себя идентично printf () , но при этом должны включать информацию, подобную java stacktrace. Вот пример основного:
В результате получается следующий результат:
источник
#include
на<stdio.h>
Используйте
__LINE__
(это двойное подчеркивание LINE двойное подчеркивание), препроцессор заменит его номером строки, на которой он встречается.источник
Касса
__FILE__
и__LINE__
макросыисточник
C ++ 20 предлагает новый способ добиться этого, используя std :: source_location . В настоящее время это доступно в gcc и clang как
std::experimental::source_location
с#include <experimental/source_location>
.Проблема с подобными макросами
__LINE__
заключается в том, что если вы хотите создать, например, функцию ведения журнала, которая выводит текущий номер строки вместе с сообщением, вам всегда нужно передавать__LINE__
как аргумент функции, потому что он раскрывается на месте вызова. Что-то вроде этого:Всегда выводит строку объявления функции, а не строку, из которой
log
был вызван. С другой стороны, с помощьюstd::source_location
можно написать примерно так:Здесь
loc
инициализируется номером строки, указывающим на место, откудаlog
был вызван. Вы можете попробовать это онлайн здесь.источник
Попробуй
__FILE__
и__LINE__
.Вы также можете найти
__DATE__
и__TIME__
полезные.Хотя, если вам не нужно отлаживать программу на стороне клиента и, следовательно, регистрировать эту информацию, вам следует использовать обычную отладку.
источник
raw code
(например: `__`). @mmyers попытался помочь, но он избежал только одного из подчеркиваний, и поэтому у вас остался синтаксис разметки для курсива . Впрочем, я согласен с тем, что голоса против здесь немного резкие.Для тех, кому это может понадобиться, макрос "FILE_LINE" для простой печати файла и строки:
источник
Поскольку сейчас я тоже столкнулся с этой проблемой, и я не могу добавить ответ на другой, но также действительный вопрос, заданный здесь , я предоставлю пример решения проблемы: получение только номера строки, в которой была вызвана функция. C ++ с использованием шаблонов.
Предпосылки: в C ++ в качестве аргумента шаблона можно использовать целочисленные значения, не являющиеся типами. Это отличается от типичного использования типов данных в качестве аргументов шаблона. Идея состоит в том, чтобы использовать такие целые числа для вызова функции.
Вывод:
Здесь следует упомянуть, что в стандарте C ++ 11 можно указать значения шаблона по умолчанию для функций, использующих шаблон. В до C ++ 11 значения по умолчанию для аргументов, не являющихся типами, похоже, работают только для аргументов шаблона класса. Таким образом, в C ++ 11 не было бы необходимости иметь повторяющиеся определения функций, как указано выше. В С ++ 11 также допустимо иметь аргументы шаблона const char *, но их невозможно использовать с литералами, подобными
__FILE__
или__func__
упомянутыми здесь .Так что, в конце концов, если вы используете C ++ или C ++ 11, это может быть очень интересной альтернативой, чем использование макросов для получения вызывающей строки.
источник
Пользуюсь
__LINE__
, а какой у нее тип?Как целочисленная константа , код часто может предполагать, что значение равно,
__LINE__ <= INT_MAX
и поэтому тип равенint
.Для печати в C,
printf()
нуждается в соответствующем спецификатор:"%d"
. Это гораздо меньшая проблема в C ++ сcout
.Педантичное беспокойство: если номер строки превышает
INT_MAX
1 (что несколько возможно с 16-битнымint
), можно надеяться, что компилятор выдаст предупреждение. Пример:В качестве альтернативы, код может заставить более широкие типы предупреждать такие предупреждения.
Избегайте
printf()
Чтобы избежать всех целочисленных ограничений: stringify . Код можно было печатать напрямую без
printf()
вызова: приятная вещь, которую следует избегать при обработке ошибок 2 .1 Конечно, плохая практика программирования для такого большого файла, но, возможно, машинный код может стать слишком большим.
2 При отладке иногда код просто не работает должным образом. Вызов сложных функций, таких как вызов
*printf()
простых функций, может вызвать проблемыfputs()
.источник