【问题标题】:C function pointer assignment warningC 函数指针赋值警告
【发布时间】:2016-04-13 18:16:56
【问题描述】:

我有一个函数(特别是系统调用),它返回需要调用的函数的结果。

代码是这样的

    int32_t (*func_ptr)(int32_t fd, void * buf, int32_t nbytes);
    func_ptr = (curr_proc->fds[fd].operations_pointer[READ]);

我们的curr_proc 只是一个结构。这个结构持有一个文件描述符数组(fds),它包含一个指向要运行的相应函数的指针(operations_pointer)。有一个数组保存了我们系统中每种设备的函数,这个数组看起来像这样:

uint32_t * rtc_ops_table[4] = {(uint32_t *) rtc_open, (uint32_t *) rtc_read, (uint32_t *) rtc_write, (uint32_t *) rtc_close};
uint32_t * dir_ops_table[4] = {(uint32_t *) dir_open, (uint32_t *) dir_read, (uint32_t *) dir_write, (uint32_t *) dir_close};

因此,当程序调用 read 时,相应的函数指针被加载到 func_ptr 中,然后返回其相应的参数。

我遇到的问题是,在我分配func_ptr 的行中,我从 gcc 收到了这个警告:

warning: assignment makes pointer from integer without a cast

我尝试过各种类型的转换,例如(uint32_t *)(uint32_t)(int32_t) 等。我也尝试过这样分配函数指针:

func_ptr = &(curr_proc->fds[fd].operations_pointer[READ]);

但无济于事。

我该如何解决这个警告?

编辑:

这是 curr_prc 的结构

typedef struct {
    file_array fds[8];
    uint8_t file_names[8][32];
    uint8_t proc_num;
    ...
} pcb_t;

还有 fas 的结构体:

typedef struct file_array{
    uint32_t * operations_pointer;
    inode_t * inode;
    uint32_t file_position;
    uint32_t flags;
} file_array;

【问题讨论】:

  • 提交curr_proc的类型声明怎么样?在不知道实际涉及的类型是什么的情况下,很难解决类型问题。
  • 也是curr_proc->fds的元素类型的声明。
  • @JohnBollinger 更新
  • operations_pointer 只是指向 uint32_t 的指针,而不是指向函数的指针。我认为这就是错误所在。 Operations_pointer 应该与 func_ptr 具有相同的类型。那些 ops_table 数组可能还应该有一个函数指针类型——你需要强制转换为 uint32_t 指针数组的数组。

标签: c function-pointers


【解决方案1】:

尝试这样的事情(当然,将行放在它们所属的代码中):

typedef int32_t (*my_func_ptr)(int32_t fd, void * buf, int32_t nbytes);

typedef struct file_array{
    my_func_ptr operations_pointer[4];
    inode_t * inode;
    uint32_t file_position;
    uint32_t flags;
} file_array;

my_func_ptr rtc_ops_table[4] = {rtc_open, rtc_read, rtc_write, rtc_close};
my_func_ptr dir_ops_table[4] = {dir_open, dir_read, dir_write, dir_close};

my_func_ptr func_ptr = (curr_proc->fds[fd].operations_pointer[READ]);

在本例中,my_func_ptr 是一种描述函数指针并用于包含它们的所有变量的类型。

或者,您可能希望将操作指针声明为指针:

 my_func_ptr *operations_pointer;

这样您就可以让它指向您的两个操作表之一:

curr_proc->fds[fd].operations_pointer = rtc_ops_table;

那么您可以像使用 ops_table 数组之一一样使用操作指针。

【讨论】:

    【解决方案2】:

    file_array中的operations_pointer应该是functoin指针类型(func_ptr),是uint32_t指针!

    【讨论】:

      【解决方案3】:

      函数指针和对象指针与C不同。它们之间不能直接转换,只能将函数指针转换为void *类型,这是一个对象指针类型。

      此外,如果打算让file_array.operations_pointer 指向函数指针的动态数组,那么您需要额外的间接级别。

      也许你想要这样的东西,而不是:

      typedef struct file_array{
          int (**operations_pointer)();
          inode_t * inode;
          uint32_t file_position;
          uint32_t flags;
      } file_array;
      

      这将operations_pointer 声明为一个指针,该指针指向一个函数,该函数接受未指定的参数并返回一个int。这将适用于动态分配的函数指针块。您的 C 编译器可能会抱怨缺少函数原型,这是正确的:该形式不表达指向函数的参数类型,但如果这些函数并非都具有兼容的签名,则这是合适的。

      如果您打算存储的所有函数指针都指向具有相同签名的函数,那么最好在类型声明中表达该签名:

      typedef struct file_array{
          int (**operations_pointer)(int32_t, void *, int32_t);
          inode_t * inode;
          uint32_t file_position;
          uint32_t flags;
      } file_array;
      

      如果它们的签名不同,那么它们至少必须具有相同的返回类型,因为你不能在不指定返回类型的情况下表达函数指针。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-09
        • 2019-06-09
        • 1970-01-01
        • 1970-01-01
        • 2013-01-23
        • 2019-01-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多