ФлеймФорумПрограммирование

C++ - задачка.

Страницы: 1 2 3 4 Следующая »
#0
10:20, 27 июня 2019

Есть функция:

#if defined _DEBUG
void debug_error(const wchar_t message[]);
#endif

Есть макросы:

#if defined _DEBUG
#define DEBUG_ERROR(message) debug_error(L ## message)
#define DEBUG_ASSERT(expression) if (!(expression)) DEBUG_ERROR(#expression)
#else
#define DEBUG_ERROR(message) NOOP
#define DEBUG_ASSERT(expression) NOOP
#endif

Собсна debug_error не должна дергаться напрямую, а использоваться только из макросов DEBUG_ERROR, DEBUG_ASSERT.
Хотелось бы, чтоб при попытке использовать функцию напрямую компилятор выдавал ошибку или предупреждение.
Можно как-то такое реализовать?

#1
10:30, 27 июня 2019

нельзя

#2
10:38, 27 июня 2019

Не делать объявление функции debug_error. Вместо этого сделать еще один obj-файл, в котором будет функция с дурацким именем (которое трудно запомнить и написать), просто вызывающая внутри себя debug_error. В требуемых файлах объявлять эту функцию с дурацким именем и в макросах использовать его же.

То есть, прямого запрета вроде как нет, но при желании воспользоваться напрямую надо будет либо писать дурацкое имя, либо дополнительно делать объявление исходной debug_error.

#3
10:39, 27 июня 2019

Dmitry_Milk
Ну вот debug_error это у меня и есть та самая функция с дурацким именем )

#4
10:47, 27 июня 2019

Оно недостаточно дурацкое :) То есть оно является плохой "защитой от дурака", который по глупости своей захочет что-то отдебажить напрямую этой функцией. Защиты от хакера конечно нет.

#5
11:12, 27 июня 2019

Dmitry_Milk
Переименовал в:

debug_error_do_not_use_it_directly
#6
11:13, 27 июня 2019

Вариант первый, пусть компилятор спокойно вырежет вызов этой функции из готового кода:

void debug_error(const wchar_t message[]);

#if defined _DEBUG
void debug_error(const wchar_t message[]) {
.... МНОГО_МНОГО_КОДА
}
#else
void debug_error(const wchar_t message[]) {
// НЕТ_КОДА
}
#endif

Вариант второй, больше функционала, тяжелее использовать:

void debug_error(const wchar_t message[], char * file, int line);

#if defined _DEBUG
#define DEBUG_ERROR(message) debug_error(L ## message, __FILE__, __LINE__)
#define DEBUG_ASSERT(expression) if (!(expression)) DEBUG_ERROR(#expression)
#else
#define DEBUG_ERROR(message) NOOP
#define DEBUG_ASSERT(expression) NOOP
#endif

Оба варианта сочетаемы друг с другом ;)

#7
11:19, 27 июня 2019

Ogra
Суть не в том, как реализовать функцию debug_error, а в том,
чтоб заставить компилятор ругаться, если эта функция дергается не из макроса.
Пока остановился на полумере - обозвать debug_error дурацким именем,
дабы разработчику было лень дергать ее напрямую ( -__- )

#8
11:22, 27 июня 2019

nes
Сам понимаешь, что нельзя заставить компилятор на это ругаться. Для компилятора нет такой вещи, как препроцессор и макросы. А функции - есть.

Добавить функционал, поставив туда через макрос __FILE__ и __LINE__ - очень полезно (серьезно), и никакого уже желания вызывать функцию руками уже нету.

PS. Есть конечно, жесткий вариант, который работает - не делать функцию вообще, а весь функционал сложить в макрос.

#9
11:36, 27 июня 2019

nes
Достаточно просто предположить что человек который будет использовать твою либу - адекватный и умеет читать, поэтому можно добавить комментарий

// Do not use directly, use macro instead
#10
11:54, 27 июня 2019

nes
Дать функции debug_error атрибут deprecated, макрос DEBUG_ERROR сделать функцией, внутри делать преобразование аргумента в wchar_t, перед вызовом функции debug_error поставить команду препроцессора, чтобы не давал варнинг на вызов deprecated функции, после вызова функции возвращать всё на место.

Да, понты с преобразованием строки, но лучше ничего не придумал.

#11
13:32, 27 июня 2019

nes
Давай смотреть на вещи реально. Кто кроме тебя будет пользоваться твоей либой? Мне кажется, что только ты и будешь пользоваться, а потому эта защита не имеет никакого смысла. Плюс в любой момент ты можешь очень легко ее добавить, так что не отвлекайся лучше на такие мелочи.
А теперь насчет лога. Чего он у тебя такой не информативный? Очень как-то скромно.

+ Мой лог для Си

Сразу прошу прощения за плохую читаемость кода. Изначально макросы вообще были в одну строку, так тут уже все давно отлажено и я сюда не заглядываю.

#12
13:58, 27 июня 2019

Vlad2001_MFS
При чем тут лог?
Это у меня ассерт, единственная его задача - выдать сообщение
о проваленной проверке и ввалиться в функцию, в которой эта проверка провалилась.

#13
14:40, 27 июня 2019

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

Тем не менее, как вариант реализации: сделать шаблон со статик ассертом или enable_if. В макросе передавать единственно верный шаблонный параметр. Возможно, получится придумать и более эффективные способы через шаблон, там в 17 стандарте довольно интересные вещи завезли.

Ещё можно заморочиться с LLVM. Написать матчер, который сгенерирует ассерты в нужных случаях. Не помню, есть ли там отдельно макроопределения, но в любом случае можно реализовать через локальные объявления в самом макросе.

#14
14:42, 27 июня 2019

nes
> Хотелось бы, чтоб при попытке использовать функцию напрямую компилятор выдавал
> ошибку или предупреждение.

Для этого достаточно попытаться скомпилировать уже приведённый твой код без _DEBUG - т.к. самой функции в этом случае не будет, то посыпятся ошибки.
Не очень понятно поэтому с чем именно ты пытаешься бороться - защита от дурака как бы уже есть в достаточном объёме.

Страницы: 1 2 3 4 Следующая »
ФлеймФорумПрограммирование

Тема в архиве.