C 断言宏的多个错误
Multiple errors from C assert macro
我有一个断言宏定义为:
#define likely(cond) (__builtin_expect((cond), 1))
#define unlikely(cond) (__builtin_expect(!!(cond), 0))
static void assert_fail(const char *__assertion, const char *__file,
unsigned int __line, const char *__function) {
fprintf(stderr, "\nASSERT failed %s:%d %s()\n%s\n", __file, __line, __function, __assertion);
void *array[50];
size_t size = backtrace(array, 50); // Fill out array of pointers to stack entries
backtrace_symbols_fd(&array[1], size, STDERR_FILENO);
exit(1);
}
#define assert(expr) ( likely(expr) ? (void) (0) : \
assert_fail(#expr, __FILE__, __LINE__, __func__ ))
这很好用,除非你在断言条件中犯了一个简单的错误,例如错误的变量名:
assert(size > 0);
它打印出一个完全合理的错误,然后是 5 个注释(包括重复),这使得它更难阅读。有什么理智的方法可以解决这个问题,让它更容易阅读吗?核心问题似乎是宏的使用,但考虑到 __FILE__
、__LINE__
等的使用,我在这里看不到如何避免它。
如果可能的话,禁用 "note: each undeclared identifier is reported only once for each function" 会把它减半(尽管我找不到任何方法来做到这一点)
abc.c: In function 'init':
abc.c:53:12: error: 'size' undeclared (first use in this function)
assert(size > 0);
^
include/assert.h:21:41: note: in definition of macro 'likely'
#define likely(cond) (__builtin_expect((cond), 1))
^
abc.c:53:5: note: in expansion of macro 'assert'
assert(size > 0);
^
abc.c:53:12: note: each undeclared identifier is reported only once for each function it appears in
assert(size > 0);
^
include/assert.h:21:41: note: in definition of macro 'likely'
#define likely(cond) (__builtin_expect((cond), 1))
^
abc.c:53:5: note: in expansion of macro 'assert'
assert(size > 0);
^
如果表达式的计算结果为 TRUE,则 assert() 不执行任何操作。如果表达式的计算结果为 FALSE,assert() 在 stderr(显示错误消息和诊断的标准错误流)上显示错误消息并中止程序执行。
作为一般规则,在处理编译器错误时,您会解决您发现的第一个错误,然后重新编译。这样您就不会浪费时间追查级联错误。
在这种特殊情况下,您会注意到有一个 "error" 行后跟几行 "note" 行。每当您看到 "note" 消息时,它都会为您提供有关最近 "error" 或 "warning message" 的附加信息。您不应该隐藏此类消息(我不相信您可以),因为它们可以为您提供有关错误真正来源的宝贵信息。
下面是这些 "note" 消息有用处的示例:
#include <stdio.h>
void f1(double x);
int main()
{
f1(3);
return 0;
}
void f1(int x)
{
printf("x=%d\n", x);
}
在此代码中,f1
的声明与定义不匹配。编译器生成以下消息:
x1.c:12:6: error: conflicting types for ‘f1’
void f1(int x)
^
x1.c:3:6: note: previous declaration of ‘f1’ was here
void f1(double x);
"error" 消息告诉您第 12 行的定义与声明不匹配,但没有说明它与什么声明冲突。这出现在随后的 "note" 消息中。在大型项目中,如果没有 "note" 消息,您可能很难找到该冲突。
我有一个断言宏定义为:
#define likely(cond) (__builtin_expect((cond), 1))
#define unlikely(cond) (__builtin_expect(!!(cond), 0))
static void assert_fail(const char *__assertion, const char *__file,
unsigned int __line, const char *__function) {
fprintf(stderr, "\nASSERT failed %s:%d %s()\n%s\n", __file, __line, __function, __assertion);
void *array[50];
size_t size = backtrace(array, 50); // Fill out array of pointers to stack entries
backtrace_symbols_fd(&array[1], size, STDERR_FILENO);
exit(1);
}
#define assert(expr) ( likely(expr) ? (void) (0) : \
assert_fail(#expr, __FILE__, __LINE__, __func__ ))
这很好用,除非你在断言条件中犯了一个简单的错误,例如错误的变量名:
assert(size > 0);
它打印出一个完全合理的错误,然后是 5 个注释(包括重复),这使得它更难阅读。有什么理智的方法可以解决这个问题,让它更容易阅读吗?核心问题似乎是宏的使用,但考虑到 __FILE__
、__LINE__
等的使用,我在这里看不到如何避免它。
如果可能的话,禁用 "note: each undeclared identifier is reported only once for each function" 会把它减半(尽管我找不到任何方法来做到这一点)
abc.c: In function 'init':
abc.c:53:12: error: 'size' undeclared (first use in this function)
assert(size > 0);
^
include/assert.h:21:41: note: in definition of macro 'likely'
#define likely(cond) (__builtin_expect((cond), 1))
^
abc.c:53:5: note: in expansion of macro 'assert'
assert(size > 0);
^
abc.c:53:12: note: each undeclared identifier is reported only once for each function it appears in
assert(size > 0);
^
include/assert.h:21:41: note: in definition of macro 'likely'
#define likely(cond) (__builtin_expect((cond), 1))
^
abc.c:53:5: note: in expansion of macro 'assert'
assert(size > 0);
^
如果表达式的计算结果为 TRUE,则 assert() 不执行任何操作。如果表达式的计算结果为 FALSE,assert() 在 stderr(显示错误消息和诊断的标准错误流)上显示错误消息并中止程序执行。
作为一般规则,在处理编译器错误时,您会解决您发现的第一个错误,然后重新编译。这样您就不会浪费时间追查级联错误。
在这种特殊情况下,您会注意到有一个 "error" 行后跟几行 "note" 行。每当您看到 "note" 消息时,它都会为您提供有关最近 "error" 或 "warning message" 的附加信息。您不应该隐藏此类消息(我不相信您可以),因为它们可以为您提供有关错误真正来源的宝贵信息。
下面是这些 "note" 消息有用处的示例:
#include <stdio.h>
void f1(double x);
int main()
{
f1(3);
return 0;
}
void f1(int x)
{
printf("x=%d\n", x);
}
在此代码中,f1
的声明与定义不匹配。编译器生成以下消息:
x1.c:12:6: error: conflicting types for ‘f1’
void f1(int x)
^
x1.c:3:6: note: previous declaration of ‘f1’ was here
void f1(double x);
"error" 消息告诉您第 12 行的定义与声明不匹配,但没有说明它与什么声明冲突。这出现在随后的 "note" 消息中。在大型项目中,如果没有 "note" 消息,您可能很难找到该冲突。