C 这是不是;从指针生成不带强制转换的整数;安全的定义?
我使用以下功能自动通知用户:C 这是不是;从指针生成不带强制转换的整数;安全的定义?,c,pointers,gcc,casting,c-preprocessor,C,Pointers,Gcc,Casting,C Preprocessor,我使用以下功能自动通知用户: #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_mo
#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为enum,gcc在编译期间显示警告:
警告:(接近(匿名)[1]'的初始化)警告:初始化从指针生成整数而不进行强制转换[默认启用]
警告:(接近(匿名)[2]'的初始化)
警告:初始化从指针生成整数而不进行强制转换[默认启用]
警告:(接近(匿名)[3]'的初始化)
警告:初始化从指针生成整数而不使用强制转换[默认情况下启用] 代码工作得很好,但这真的安全吗?
如果是,如何摆脱它?我尝试使用
#pragma GCC diagnostic error“-Wpointer to int cast”
进行相应的推送和弹出操作,但没有效果。宏仅在所有指针类型大小相同且大小为32位时才有效。对于大多数系统来说,第一个条件是正确的,如果您的平台不太可能是深奥的,则可以忽略第二个条件,第二个条件当然不是
这就是说,即使是安全的,留下发出警告的代码也不是一个好主意,因为在全球范围内抑制它们同样没有吸引力。要抑制警告,您必须对每次对宏的调用应用抑制,而不仅仅是宏定义本身。在这种情况下,可能只需提供参数计数就更容易了。只有在所有指针类型大小相同且大小为32位的情况下,宏才有效。对于大多数系统来说,第一个条件是正确的,如果您的平台不太可能是深奥的,则可以忽略第二个条件,第二个条件当然不是
这就是说,即使是安全的,留下发出警告的代码也不是一个好主意,因为在全球范围内抑制它们同样没有吸引力。要抑制警告,您必须对宏的每次调用应用抑制,而不仅仅是宏定义本身。在这种情况下,仅提供参数计数可能会更容易。您正在尝试对日志宏中的参数数量进行计数。请查看。您正在尝试计算日志宏中的参数数。请查看。代码有效:
- 指针类型的
的首次初始化将永远不会成功 溢出该值。将会丢失信息,但什么也没有 更多uint32\t
- 然后你也只使用
这样的野兽,所以这个化合物 文字永远不会被计算sizeof
0
参数不起作用,因此最好删除gccish,##
技巧和+-1
游戏
正如其他人所说,向代码的用户强加一系列警告是非常糟糕的风格。这样的事情永远不应该通过审查
最后,有些宏仅使用标准C(C99)来实现相同的目标,例如P99\u NARG
from.代码有效:
- 指针类型的
的首次初始化将永远不会成功 溢出该值。将会丢失信息,但什么也没有 更多uint32\t
- 然后你也只使用
这样的野兽,所以这个化合物 文字永远不会被计算sizeof
0
参数不起作用,因此最好删除gccish,##
技巧和+-1
游戏
正如其他人所说,向代码的用户强加一系列警告是非常糟糕的风格。这样的事情永远不应该通过审查
最后,还有一些宏只使用标准C(C99)来实现相同的目标,例如
P99\u NARG
from.关于指针大小。如果我使用memsize类型,比如size\u t而不是int32\u t,会怎么样?在相应的系统指针上,它将是32位和64位,指向整数类型转换,反之亦然,如果没有类型转换,则不可能实现。计算参数的解决方案可用于同质类型的参数。@user1969104:它不是“我的解决方案”,宏中使用的logger()函数似乎将参数计数作为参数,宏试图自动确定参数计数。更好的解决方案是使用更好的接口编写日志函数。@pugnator:定义的类型intptr\u t或uintptr\u t(在stdint.h中)可能是更好的选择。关于指针大小。如果我使用memsize类型,比如size\u t而不是int32\u t,会怎么样?在相应的系统指针上,它将是32位和64位,指向整数类型转换,反之亦然,如果没有类型转换,则不可能实现。计算参数的解决方案可用于同质类型的参数。@user1969104:它不是“我的解决方案”,宏中使用的logger()函数似乎将参数计数作为参数,宏试图自动确定参数计数。更好的解决方案是使用更好的接口编写日志函数。@pugnator:定义的类型intptr\u t或uintptr\u t(在stdint.h中)可能是更好的选择。您试图实现什么sizeof((int32_t[]){0,###(uu VA_uargs_u})
看起来不是很有用。是否要计算varg列表中的元素数?还有其他方法可以达到这个目的。你想达到什么目的sizeof((int32_t[]){0,###(uu VA_uargs_u})
看起来不是很有用。是否要计算varg列表中的元素数?还有其他方法可以实现这一目标。