使用宏禁用功能

发布于 2024-12-09 06:54:09 字数 1048 浏览 1 评论 0原文

在互联网上搜索了很多解决方案后,我决定在这里询问我的解决方案是否良好。

我正在尝试编写一个简单且模块化的 C 日志记录库,旨在轻松禁用,并特别帮助博士生和研究人员调试算法,尽可能减少日志记录系统的影响。

我的问题是,我希望库的用户可以在编译时禁用日志记录系统,生成一个可执行文件,其中记录器的成本为 0。C

代码如下所示:

...
logger_t * logger;

result = logger_init(logger);
if(result == -1) {...}
...

这将简单地初始化记录器。寻找示例代码时,我检查了assert.h标头,但在我的情况下,该解决方案会产生警告列表。事实上,如果使用宏将 logger_init() 替换为 0,这将导致变量 logger 从未被使用。

出于这个原因,我决定使用这种方法:

int logger_init(logger_t *logger);

#ifndef NLOG /* NLOG not defined -> enable logging */
int logger_init(logger_t *logger) {
...
}
#else  /* NLOG defined --> the logging system must be disabled */
#define logger_init(logger)     (int)((logger = NULL) == NULL)
#endif /* NLOG */

这不会导致警告,而且我还避免了调用该函数的开销。事实上,我的第一次尝试是这样做的:

int logger_init(logger_t *logger) {
  #ifndef NLOG /* NLOG not defined -> enable logging */
  ...
  #endif
  return 0;
}

即使我不需要它,也继续调用该函数。

您认为我的解决方案可以被认为是一个好的解决方案吗?有更好的解决方案吗?

非常感谢,伙计们! 干杯, 阿曼多

After searching quite a bit in the Internet for a solution I decided to ask here if my solution is fine.

I'm trying to write a simple and modular C logging library intended to be simple to disable and specially helping PhD students and researchers to debug an algorithm reducing as much as possibile the impact of the logging system.

My problem is that I want make possible for the user of the library to disable the logging system at compile time producing an executable in which the cost of the logger is 0.

The C code would look like this:

...
logger_t * logger;

result = logger_init(logger);
if(result == -1) {...}
...

this will simply initialize the logger. Looking for an example code I have checked the assert.h header but that soulution results in a list of warnings in my case. In fact, if logger_init() is substituted by 0 using the macro this will result in the variable logger never used.

For this reason I've decided to use this approach:

int logger_init(logger_t *logger);

#ifndef NLOG /* NLOG not defined -> enable logging */
int logger_init(logger_t *logger) {
...
}
#else  /* NLOG defined --> the logging system must be disabled */
#define logger_init(logger)     (int)((logger = NULL) == NULL)
#endif /* NLOG */

this does not result in warnings and I also avoid the overhead of calling the function. In fact my first try was to do like this:

int logger_init(logger_t *logger) {
  #ifndef NLOG /* NLOG not defined -> enable logging */
  ...
  #endif
  return 0;
}

keep calling the function even if I do not need it.

Do you think my solution could be considered a good solution? Is there a better solution?

Thanks a lot, guys!
Cheers,
Armando

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一直在等你来 2024-12-16 06:54:09

至少在 90 年代,标准习惯用法是:

#ifndef NLOG
void logger_init(logger_t *logger);
void logger_log(logger_t *logger, ...);
#else
#define logger_init (void)sizeof
#define logger_log  (void)sizeof
#endif

请记住,尽管对 sizeof 操作数进行了语法检查,但它们并未被求值。
这个技巧也适用于可变参数函数,因为 sizeof 运算符将看到带有多个逗号运算符的表达式:

logger_log(log, 1, 2, 3);

转换为:

(void)sizeof(log, 1, 2, 3);

这些逗号不是分隔参数(sizeof 不是函数而是运算符),但它们是逗号运算符

请注意,我将返回值从 int 更改为 void。确实没有必要,但是 sizeof 返回几乎没有意义。

The standard idiom for that, at least in the 90s, was:

#ifndef NLOG
void logger_init(logger_t *logger);
void logger_log(logger_t *logger, ...);
#else
#define logger_init (void)sizeof
#define logger_log  (void)sizeof
#endif

Remember that sizeof operands are not evaluated, although they are syntax checked.
This trick works also with variadic functions, because the sizeof operator will see an expresion with several comma operators:

logger_log(log, 1, 2, 3);

Converts to:

(void)sizeof(log, 1, 2, 3);

Those commas are not separating parameters (sizeof is not a function but an operator), but they are comma operators.

Note that I changed the return value from int to void. No real need for that, but the sizeof return would be mostly meaningless.

扮仙女 2024-12-16 06:54:09

你的禁用版本不能只是一个常量吗:

#ifndef NLOG /* NLOG not defined -> enable logging */
int logger_init(logger_t *logger) {
...
}
#else  /* NLOG defined --> the logging system must be disabled */
#define logger_init(logger)     0
#endif /* NLOG */

这样,你就拥有(预编译后): result = 0; ,它不应该产生任何警告。

Can't your disabled version simply be a constant:

#ifndef NLOG /* NLOG not defined -> enable logging */
int logger_init(logger_t *logger) {
...
}
#else  /* NLOG defined --> the logging system must be disabled */
#define logger_init(logger)     0
#endif /* NLOG */

This way, you just have (after pre-compilation): result = 0; which shouldn't produce any warnings.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文