gpt4 book ai didi

c - 带有 __va_args__ 和括号的宏错误

转载 作者:太空宇宙 更新时间:2023-11-04 04:24:32 25 4
gpt4 key购买 nike

我已经从互联网上下载并重新编译了一个库,结果是由于非法指针地址导致核心转储。

查看源码,涉及的语句有:

#define E_DEBUG(level, ...) \
if (err_get_debug_level() >= level) \
err_msg(ERR_DEBUG, FILELINE, __VA_ARGS__)
#define E_DEBUGCONT(level, ...) \
if (err_get_debug_level() >= level) \
err_msg(ERR_DEBUG, NULL, 0, __VA_ARGS__)

以及崩溃的行:

E_DEBUGCONT(1, (" %d", i));

事实上,编译器对此发出了警告:

In file included from ptm_mgau.c:56:0:
ptm_mgau.c: In function ‘ptm_mgau_calc_cb_active’:
ptm_mgau.c:317:30: warning: left-hand operand of comma expression has no effect [-Wunused-value]
E_DEBUGCONT(1, (" %d", i));
^
/home/pma/actual/pocketsphinx/pocketsphinx-5prealpha/../sphinxbase-5prealpha/include/sphinxbase/err.h:142:37: note: in definition of macro ‘E_DEBUGCONT’

ptm_mgau.c:317:24: warning: passing argument 4 of ‘err_msg’ makes pointer from integer without a cast [-Wint-conversion]
E_DEBUGCONT(1, (" %d", i));
^
/home/pma/actual/pocketsphinx/pocketsphinx-5prealpha/../sphinxbase-5prealpha/include/sphinxbase/err.h:142:37: note: in definition of macro ‘E_DEBUGCONT’

/home/pma/actual/pocketsphinx/pocketsphinx-5prealpha/../sphinxbase-5prealpha/include/sphinxbase/err.h:159:1: note: expected ‘const char *’ but argument is of type ‘int’
err_msg(err_lvl_t lvl, const char *path, long ln, const char *fmt, ...);

编译器对将要发生的事情非常准确:在表达式 ( "%d", i ) 中意味着忽略 "%d" 并得到 的值我。后来,这个i被用作指针,导致崩溃。

代码的作者似乎期望宏扩展会产生以下行:

if (err_get_debug_level() >= level) \
err_msg(ERR_DEBUG, NULL, 0, " %d", i)

但是预处理器产生:

if (err_get_debug_level() >= level) \
err_msg(ERR_DEBUG, NULL, 0, ( " %d", i) )

有什么方法可以解决这个问题,更改宏定义而不是一条一条地检查所有 DEBUG 语句(数百个)?

** 附录 **

重现该问题的一个最小示例是,编译并执行以下代码:

#include <stdio.h>
#include <stdarg.h>

#define ERR_DEBUG 1
#define FILELINE __FILE__ , __LINE__

void err_msg(int lvl, const char *path, long ln, const char *fmt, ...) {

char msg[1024];

va_list ap;

va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);

printf("%s\n",msg);

}

#define E_DEBUG(level, ...) \
err_msg(ERR_DEBUG, FILELINE, __VA_ARGS__)

int main ( void ) {
E_DEBUG(1,("%d",14));
}

最佳答案

有点像

#define PASTE(...) __VA_ARGS__

/*PASTE __VA_ARGS__ */

将删除括号,但这取决于括号始终存在。

应用于你的例子,这个:

#define PASTE(...) __VA_ARGS__


#define E_DEBUG(level, ...) \
if (err_get_debug_level() >= level) \
err_msg(ERR_DEBUG, FILELINE, PASTE __VA_ARGS__)

#define ERR_DEBUG 1
#define FILELINE __FILE__ , __LINE__

int err_get_debug_level(void);
void err_msg(int lvl, const char *path, long ln, const char *fmt, ...);


int main ( void ) {
E_DEBUG(1,("%d",14));
}

编译。

关于c - 带有 __va_args__ 和括号的宏错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43032244/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com