我使用以下函数为用户进行自动通知:
#define LOG(...) logger((sizeof((int32_t[]){0, ## __VA_ARGS__})/sizeof(int32_t)-1), __VA_ARGS__)
..................
void informer(int32_t count, ...)
{
GtkTreeModel *model = 0;
GtkTreeIter iter;
model = gtk_tree_view_get_model(GUI.log_view);
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
char log_body[16384] = {0};
/* Add current time */
GDateTime *now;
char *time;
now = g_date_time_new_now_local ();
time = g_date_time_format (now, "%c");
g_date_time_unref (now);
gtk_list_store_set(GTK_LIST_STORE(model), &iter, LOG_TIME, time, -1);
free(time);
/* Parse input data*/
va_list ap;
va_start(ap, count);
while (count--) {
if(!count)
{
enum error_type type = va_arg(ap, int);
if(type == OK)
{
gtk_list_store_set(GTK_LIST_STORE(model), &iter, LOG_TYPE, "OK", -1);
}
.............................................
else
{
gtk_list_store_set(GTK_LIST_STORE(model), &iter, LOG_TYPE, "Неизв.", -1);
}
break;
}
char* arg = va_arg(ap, char*);
strcat(log_body," ");
strcat(log_body,arg);
}
va_end(ap);
gtk_list_store_set(GTK_LIST_STORE(model), &iter, LOG_BODY, log_body, -1);
}
所以在这样的电话中
LOG("Unknown error", "Error!", ERROR);
其中ERROR为枚举,gcc在编译期间显示警告:
警告:(接近初始化'(匿名)[1]')
警告:初始化从指针生成整数而没有强制转换[默认启用]
警告:(接近初始化'(匿名)[2]')
警告:初始化从指针生成整数而没有强制转换[默认启用]
警告:(接近初始化'(匿名)[3]')
警告:初始化从指针生成整数而没有强制转换[默认启用]
代码完美无缺,但实际安全吗?
如果是的话,如何摆脱它?我尝试使用#pragma GCC diagnostic error "-Wpointer-to-int-cast"
相应的推送和弹出,但没有效果。
答案 0 :(得分:1)
宏仅在所有指针类型大小相同且大小为32位的情况下有效。对于大多数系统来说,第一个条件是正确的,并且如果你的平台不太可能是一个深奥的东西,可能会被忽略,第二个条件肯定不是。
那就是说,即使它是安全的,留下发出警告的代码也不是一个好主意,并且全局压制它们同样没有吸引力。要禁止警告,您必须将抑制应用于对宏的每次调用,而不仅仅是宏定义本身,在这种情况下,提供参数计数会更容易。
答案 1 :(得分:1)
您正在尝试计算LOG宏中的参数数量。请查看possible solutions here。
答案 2 :(得分:1)
代码有效:
uint32_t
溢出那个价值。会丢失信息,但什么也没有
更多。sizeof
这样的野兽,所以这个化合物
文字永远不会被评估。从错误的角度来看,无论如何,你的0
参数都不适用,所以最好用, ##
删除gccish +-1
技巧和游戏。
正如其他人所说,向代码用户强加一堆警告真的很糟糕。这样的事情永远不应该通过审查。
最后,有些宏只使用标准C(C99)来实现相同的目标,例如来自P99的P99_NARG
。