繁体   English   中英

结构函数的返回类型不兼容-C

[英]incompatible return type from struct function - C

当我尝试按原样运行此代码时,收到编译器消息“错误:返回不兼容的类型”。 我在代码中标记了错误的位置。 如果我把这句话排除在外,那么编译器很高兴。

问题是我想返回一个表示无效输入的值给函数(在这种情况下,该函数调用f2(2)。)我只希望在不使用2作为参数的情况下调用函数时返回带有数据的结构。

我觉得只有两种方法可以去:

  1. 使函数返回一个结构指针而不是一个死机结构,但是我的调用者函数看起来会很有趣,因为我必须将yb更改为y-> b,并且由于需要额外的步骤来获取内存中的数据,因此操作可能会变慢。

  2. 分配额外的内存,零字节填充它,然后将返回值设置为内存中该位置的结构。 (示例: return x[nnn];而不是return x[0]; )。 这种方法将使用更多的内存和一些处理以零字节填充它。

最终,我正在寻找一种从长远来看最快,最干净的解决方案(就代码而言)。 如果必须使用->来寻址元素的成员,那么我想这就是要走的路。

有没有人拥有使用CPU功耗最少的解决方案?

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

    typedef struct{
    long a;
    char b;
    }ab;

    static char dat[500];

    ab f2(int set){
      ab* x=(ab*)dat;
      if (set==2){return NULL;}
      if (set==1){
      x->a=1;
      x->b='1';
      x++;
      x->a=2;
      x->b='2';
      x=(ab*)dat;
      }
      return x[0];
    }

    int main(){
      ab y;
      y=f2(1);
      printf("%c",y.b);
      y.b='D';
      y=f2(0);
      printf("%c",y.b);
      return 0;
    }

如果您关心速度,则它是特定于实现的。

请注意,在Linux 的x86-64 ABI定义了一个struct (准确) 的标量成员(即整数,双打,或指针,哪位都适合在一台机器登记册,但不是struct等等......这都是集合数据)通过两个寄存器(不通过堆栈)返回,这非常快。

BTW

      if (set==2){return NULL;} //wrong

显然是错误的。 您可以编写以下代码:

   if (set==2) return (aa){0,0};

也,

 ab* x=(ab*)dat; // suspicious

对我来说似乎很可疑(因为稍后return x[0]; )。 您不能保证dat对齐(例如8或16字节),在某些平台上(尤其是x86-64),如果dat不对齐,则至少会降低性能(实际上,这是未定义的行为 )。

顺便说一句,我建议始终返回诸如return (aa){l,c};类的指令return (aa){l,c}; (其中l是可转换为long的表达式, c是可转换为char的表达式); 这可能是最容易读取的,并且将进行优化以加载两个返回寄存器。

当然,如果您关心性能,出于基准测试的目的,应该启用优化(和警告),例如,如果使用GCC ,请使用gcc -Wall -Wextra -O2 -march=native进行编译 在我的系统上(带有GCC 5.2的Linux / x86-64),小功能

  ab give_both(long x, char y)
  { return (ab){x,y}; }

被编译(使用gcc -O2 -march=native -fverbose-asm -S )为:

         .globl  give_both
         .type   give_both, @function
 give_both:
 .LFB0:
         .file 1 "ab.c"
         .loc 1 7 0
         .cfi_startproc
 .LVL0:
         .loc 1 7 0
         xorl    %edx, %edx      # D.2139
         movq    %rdi, %rax      # x, x
         movb    %sil, %dl       # y, D.2139
         ret
         .cfi_endproc

您会看到所有代码都在使用寄存器,而根本没有使用内存。

我将返回值用作错误代码,调用者将指针传递给他的struct例如:

int f2(int set, ab *outAb); // returns -1 if invalid input and 0 otherwise

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM