如何在 C 的 _generic 中将 char 当作 char 处理

5

我正在设计一个通用队列

https://github.com/Bhaumik-Tandan/Generic_queue_in_c

但是,我在为所有数据类型创建通用函数 enqueue 时遇到了问题。

#define enqueue(s,a) _Generic(a, int: enqueuei__19BIT0292, char*: enqueues__19BIT0292,double: enqueuef__19BIT0292,char:enqueuec__19BIT0292,float:enqueuef__19BIT0292)(s,a)

下面这行代码将 'c' 视为整数并调用相应的函数。
enqueue(s,'c')

如果我想调用 char 类型的函数,就需要写

enqueue(s,(char)'c')

我知道在C语言中,字符内部被当作整数处理,但是有没有什么方法可以解决这个问题呢?我不想每次传递字符时都写(char)括号或者创建一个新变量。


我会说不。'c'99(假设是ASCII)没有任何区别。 - Eugene Sh.
使用 enqueue(s, *"c") 可以节省 5 个字符而不必输入类型转换。否则,我认为这是不可能的。 - Yun
1
在C语言中,像'a'或'\n'这样的字符常量的类型是int,而不是char。根据定义,它是一个int类型,所以我看不到任何绕过它的方法。 - Yun
1个回答

5

您可以创建一个宏来测试参数是否为char(以'开头),如下所示:

#define is_char_literal(c) (#c[0] == '\'')

然后你可以使用一个三元表达式

#define enqueue(s,a) is_char_literal(a)? enqueuec__19BIT0292(s,a): __Generic(a, int: enqueuei__19BIT0292, char*: enqueues__19BIT0292,double: enqueuef__19BIT0292, char:enqueuec__19BIT0292, float:enqueuef__19BIT0292)(s,a)

这取决于编译器,如果你的编译器支持通过"const"评估进行优化。


1
非常聪明!它会在 enqueue(s, ('a')) 处出错,但那是一个奇怪的符号表示法。 - Yun
1
它将对enqueue(s,'a'+1)enqueue(s,1+'a')表现不同。个人而言,我会避免这样的陷阱。 - tstanisl
2
根据 https://godbolt.org/ ,在使用 -O3 标志的 GCC 中,它不会添加任何额外的开销。@Eugene Sh. - WENDYN
2
我建议将 ischar 重命名为 is_char_literal - tstanisl
1
@Yun yop,# 只是将 'c' 转换为 "\'c\'" - WENDYN
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接