C语言中使用_Generic混合函数调用并返回常量的重载函数

Cătălina Sîrbu

我看到有两种写_Generic语句的方法:

一种。

#define len(x) _Generic((x), char*:f1, int: f2, char: f3, double:f4) (x)

我想在(x)下划线

B.

#define len(x) _Generic((x), char*:f1(x), int: f2(x), char: f3(x), double:f4) 

问题是在 B 的情况下,我遇到了错误:

  1. 预期为 char* 但参数的类型为 int
  2. f...的参数 1 的不兼容类型

如果我想将函数与常量混合使用,我应该如何编写这个重载?

我试图得到:

  • 1 如果参数是 char 类型;

  • 如果参数是 char * 类型,则为字符串的长度;

  • 如果参数是 int 类型,则十进制数字的数量(当参数为负时可能增加 1);

  • 如果参数是 double 类型,则 printf() 函数使用 %f 说明符生成的字符串的长度。

     int_len(int number)
     {
         unsigned counter=0;
         if(number < 0)
         {
             counter++;
         }
    
         while(number)
         {
             counter++;
             number /= 10;
         }
         return counter;
     }
     int char_len(int param)
     {
         return 1;
     }
    
     int double_len(double param)
     {
         return 10;
     }
    
     int charptr_len(char* ptr)
     {
         unsigned count=0;
         while(*ptr)
         {
             ptr++;
             count++;
         }
         return count;
     }
    
    
     #define len(x) _Generic((x), char*:charptr_len(x), int: int_len(x), char:1, double:double_len(x))
    
     int main(void) {
         printf("%d\n",len(261321));
         printf("%d\n",len(261.321));
         printf("%d\n",len((char)'x'));
         printf("%d\n",len("A kingdom for a horse!"));
         return 0;
     }
    

ps 我知道代码可能很愚蠢,但我只是想让它工作。

卡米尔库克

我试图得到:

想象一下,编译器采用任何输入的所有路径。无论编译器采用哪条路径,对于任何输入,它们都必须“有效”,即使只使用和评估一个表达式而其余的被丢弃,从技术上讲,它们也必须“有效”。

#include <string.h>
#include <stdio.h>
#include <stdint.h>

#define len(x)  _Generic((x), \
    char: 1, \
    char *: (int)strlen((char*)(void*)(uintptr_t)x), \
    int: snprintf(NULL, 0, "%d", x), \
    double: snprintf(NULL, 0, "%f", x))

int main() {
    printf("%d\n",len(261321));
    printf("%d\n",len(261.321));
    printf("%d\n",len((char)'x'));
    printf("%d\n",len("A kingdom for a horse!"));
}

Godbolt 链接我最终使用超级转换strlen来处理strlen(261.321)案例 - 将 adouble转换为指针,以便编译器不会抱怨。"abc"如果我希望演员不要修改指针值,这并不重要这就是为什么更容易为每个案例开发单独的功能。您还可以(ab-)在泛型中使用可变参数函数参数来轻松删除任何强制转换并在您的函数中使用va_args处理它们

(小自我宣传:我最近_Generic通过开发类型安全的 printf探索了限制,使用该库,它只是#define len(x) ysprint(NULL, 0, x),但我已经看到了数字的数量逗号后的双重大小写与%fin 中的不同printf)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章