Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Функция вывода __LINE__

87
16 апреля 2009 года
Kogrom
2.7K / / 02.02.2008
Хочу сделать функцию, которая бы выводила текущий номер строки, но чтобы не требовалось это явно указывать каждый раз. При этом нужно выводить именно строку, где вызывается функция, а не где она определена. Наиболее очевидный способ:

Код:
void PrintFileAndLine(const int line, const char* file = "")
{
    cout << file << endl;
    cout << line << endl;
}
#define PRINT_FILE_AND_LINE() PrintFileAndLine(__LINE__, __FILE__)

int main()
{
    PRINT_FILE_AND_LINE();
    return 0;
}

Тут есть пара недостатков - макрос должен как-бы знать имя функции, поэтому необходимо обеспечить то, что он будет объявлен после функции. Кроме того, нельзя перенести функцию, занести ее в класс и т.п.

Второй способ:

Код:
#define LF(func) func(__LINE__, __FILE__)

void PrintFileAndLine(const int line = 0, const char* file = "")
{
    cout << file << endl;
    cout << line << endl;
}

int main()
{
    LF(PrintFileAndLine);
    return 0;
}

Вроде бы он решает перечисленные выше проблемы. Однако, синтаксис получается непонятный.

Есть ли еще какие-то варианты? В идеале, хотелось бы чтобы не было дополнительных макросов (кроме __LINE__, __FILE__).
5
16 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Kogrom
Есть ли еще какие-то варианты? В идеале, хотелось бы чтобы не было дополнительных макросов (кроме __LINE__, __FILE__).

Я не C++ник, но тупой запрос в МСДН выдал
__FUNCTION__ и __FUNCDNAME__ для декорированного имени функции, а также __FUNCSIG__ для сигнатруры.

З.Ы. В Nemerle тоже самое можно вообще своими руками сделать.

87
16 апреля 2009 года
Kogrom
2.7K / / 02.02.2008
Цитата: hardcase
Я не C++ник, но тупой запрос в МСДН выдал
__FUNCTION__ и __FUNCDNAME__ для декорированного имени функции, а также __FUNCSIG__ для сигнатруры.



1. Это имеет только косвенное отношение к C++. Все-таки макросы - это наследие C. Соответственно, я их стараюсь не применять. Но тут видно не обойтись без них.

2. МСДН в данном случае не указ (каким был бы, если бы я искал описание функций Win32 API). Данных макросов в стандартах я не нашел (в отличие от __LINE__), да и компилятор мой только __FUNCTION__ переварил.

3. Однако, я так и не понял, как данный макрос мне поможет в выводе номера текущей строки.

260
17 апреля 2009 года
Ramon
1.1K / / 16.08.2003
Никто не мешает вынести могучий макрос "#define PRINT_FILE_AND_LINE() PrintFileAndLine(__LINE__, __FILE__)" в некий h'шник. А на единицу трансляции подключив соотв. h'шник, непосредственно на месте или еще как покрутив ушами определять выводящую ф-цию.

Код:
#include "PRINT_FILE_AND_LINE.h"

void PrintFileAndLine(const int line, const char* file = "")
{
    cout << file << endl;
    cout << line << endl;
}

int main()
{
    PRINT_FILE_AND_LINE();
    return 0;
}


Да и кто сказал что это обязательно должна быть ф-ция, функциональных объектов никто не отменял.

Код:
#include "PRINT_FILE_AND_LINE.h"

struct
{
    void operator()(const int line, const char* file = "")
    {
        cout << file << endl;
        cout << line << endl;
    }
} PrintFileAndLine;

int main()
{
    PRINT_FILE_AND_LINE();
    return 0;
}


А если еще беспокоит глобальность сего то static и namespace в помощь.

PS: Требуемая универсальность слишком универсальна ибо реальная потребность ограничивается малым.
87
19 апреля 2009 года
Kogrom
2.7K / / 02.02.2008
Спасибо. О применении функциональных объектов я не подумал.
Цитата: Ramon
А если еще беспокоит глобальность сего то static и namespace в помощь.


Насколько я понимаю, static и namespace от глобальности макроса не спасут. А это меня больше всего беспокоит.

Цитата: Ramon
PS: Требуемая универсальность слишком универсальна ибо реальная потребность ограничивается малым.



Возможно. Я изучаю модуль MiniCppUnit, который применяется для тестирования. В нем весь интерфейс сделан с помощью подобных макросов, с помощью чего модуль может выводить информацию о месторасположении непрошедшего теста. Надеялся придумать альтернативу макросам, как-то их замаскировать. Думал, может шаблоны или что-то типа inline поможет, но не вышло.

260
20 апреля 2009 года
Ramon
1.1K / / 16.08.2003
[QUOTE=Kogrom]
Насколько я понимаю, static и namespace от глобальности макроса не спасут. А это меня больше всего беспокоит.
[/QUOTE]

Зато спасут от торчаших наружу символов. А локальность макроса обеспечивается независимым инклудом.
87
20 апреля 2009 года
Kogrom
2.7K / / 02.02.2008
Да все понятно. Но в моем случае этот макрос используется для модульного тестирования, и поэтому будет использован во многих местах программы. И, возможно, не одной программы. Таким образом, довольно велика вероятность, что имена макросов совпадут с какими-то другими из другого модуля от стороннего производителя. И придется производить аккуратное переименование по всему тексту программы...

Возможно, я беспокоюсь по пустякам. Но надо же было произвести небольшое исследование - вдруг бы нашел красивую альтернативу.

Однако, альтернативу вижу одну - просто не пользоваться этими макросами, журтвуя преимуществами, которые они дают.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог