【问题标题】:GCC compilation error, braces around scalar initializer [-Werror]GCC 编译错误,标量初始化器 [-Werror]
【发布时间】:2018-05-01 10:34:18
【问题描述】:

我是 C 编程新手,我尝试创建一个包含 char 和函数指针的结构,这就是问题所在。

我想更改该代码:

switch (flag) {
    case 'd':
    case 'i':
    return (my_put_nbr(va_arg(ap, int)));
    case 'p':
    return (my_putstr("0x") + my_l_base_changer(va_arg(ap, char *),
    16));
    case 'u':
    return (my_put_unbr(va_arg(ap, unsigned int)));
    case 'b':
    return (my_u_base_changer(va_arg(ap, unsigned int), 2, 0));
    case 'o':
    return (my_u_base_changer(va_arg(ap, unsigned int), 8, 0));
    case 'x':
    return (my_u_base_changer(va_arg(ap, unsigned int), 16, 0));
    case 'X':
    return (my_u_base_changer(va_arg(ap, unsigned int), 16, 1));
    default:
    return (0);
}

在那种代码中:

typedef struct fptr
{
   char op;
   int (*ptr)(va_list);
} fptr;

fptr  fptrs[]=
{
   { 's', ft_print_nb_spec },
   { 'S', ft_print_nb_up },
   { 0, NULL }
};
  int i = 0;
  while (fptrs[i++].op != flag && fptrs[i].op != 0);
  if (fptrs[i].op != 0)
  {
     fptrs[i].ptr();
  } 

我的结构包含一个函数指针,指向获得不同原型的函数

我的结构是这样的:

typedef struct action {
    char flag;
    void *function;
} action;

还有我的代码出现这样的错误:

action registers[] = {
    { 'd', (int *)(*my_put_nbr)(int) },
    { 'i', (int)(*my_put_nbr)(va_arg(ap, int)) },
    { 'p', (int)(*my_print_ptr)(va_list ap) },
    { 'u', (int)(*my_put_unbr)(va_arg(ap, unsigned int)) },
    { 'b', (int)(*my_u_base_changer)(va_arg(ap, unsigned int), 2, 0) },
    { 'o', (int)(*my_u_base_changer)(va_arg(ap, unsigned int), 8, 0) },
    { 'x', (int)(*my_u_base_changer)(va_arg(ap, unsigned int), 8, 0) },
    { 'X', (int)(*my_u_base_changer)(va_arg(ap, unsigned int), 8, 1) },
    { 0, NULL }
};

当我运行 gcc 时:

flag_nbr.c:13:28: error: expected expression before ‘int’
{ 'd', (int)(my_put_nbr)(int) },
                         ^~~
flag_nbr.c:13:28: error: missing initializer for field ‘function’ of ‘printf_action {aka struct <anonymous>}’ [-Werror=missing-field-initializers]
In file included from flag_nbr.c:8:0:
../include/my.h:21:8: note: ‘function’ declared here
void *function;
      ^~~~~~~~
flag_nbr.c:14:10: error: initialization makes pointer from integer without a cast [-Werror=int-conversion]
{ 'i', (int)(my_put_nbr)(va_arg(ap, int)) },
        ^

我不明白那个错误...

【问题讨论】:

  • action *registers[] --> action registers[]
  • 函数指针实际上看起来更像函数调用。分配函数指针时,您只需指定函数的名称。也许你应该准确地解释你这样做的目的是什么。
  • 我想要一个结构列表,其中包含一个标志和指向与标志相关的函数的指针,所以我想用这个“emule”一个 switch case 或一个 if 森林,只有ONE while 和 ONE if,像这样: int i = -1; while (fptrs[++i].op != flag && fptrs[i].op != 0); if (fptrs[i].op != 0) { fptrs[i].ptr(); }
  • 您不能通过void * 调用函数。您需要确切知道调用它的函数签名是什么,并且需要传递参数。您最好使用switch 语句来确定调用什么以及如何调用。
  • 您目前拥有的内容清晰简洁。我建议不要使用函数指针使事情变得过于复杂。

标签: c gcc compiler-errors initializer scalar


【解决方案1】:

如有疑问,请检查数据类型!!

您将变量定义为指向action 类型的指针数组。

您在初始化程序中传递的是大括号括起来的列表,它肯定与指向 action 类型的指针不匹配。

换句话说,您尝试传递一个大括号括起来的列表,而需要一个指针。现在,指针的初始值设定项应该是一个奇异值或标量,你可以称之为),所以大括号包围不是强制性的。

虽然这是完全有效的,但在大多数情况下,这可能是由您写了一些您不打算写的东西引起的(例如:您的情况!!)因此,gcc 会为此产生警告.

您可能希望更改数组类型以保存 action 类型的结构,而不是指向它们的指针。

【讨论】:

  • 好的,找到了,但是,什么是 C 中的标量初始化器?
  • 我怀疑修复它会引发更多函数指针(如果可以调用的话)使用方式的问题。
  • @dbush 好吧,手头有一个更大的问题,OP 打算如何将 FP 转换为其原始类型?
  • @SouravGhosh 没错。函数指针对于新手来说并不容易理解。
  • 我知道,但我知道如何为这种情况进行切换,但这需要很多代码行,函数指针更有用
【解决方案2】:

您正在使用 typedef 为已经具有相同名称的结构命名,请检查。 这可能不是主要原因。

【讨论】:

  • 这应该是个问题?
  • 不。我也是编程新手
  • 欢迎。您也可以考虑删除答案,因为它可能不是特别有用,正如您可能已经理解的那样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-02
  • 1970-01-01
  • 1970-01-01
  • 2013-10-07
  • 1970-01-01
  • 2011-05-26
相关资源
最近更新 更多