从结构功能不兼容的返回类型 - Ç [英] incompatible return type from struct function - C

查看:110
本文介绍了从结构功能不兼容的返回类型 - Ç的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试,因为它是运行这个code,我收到编译器消息错误:不兼容的类型的回报。我在code标记错误的位置。如果我走线出来,那么编译器是幸福的。

问题是我要重新presenting无效的输入值返回功能(在这种情况下,调用F2(2))。我只想要一个结构的数据返回如果调用函数时不使用2作为一个参数。

我觉得只有两种方式去是要么:


  1. 使函数返回,而不是一个结构指针死的结构,但后来我调用函数看起来有趣,因为我必须要改变YB为Y-> b和操作可能会比较慢,由于额外的步骤在内存中获取数据。


  2. 分配额外存储器,零字节填充它,并返回值设置为在内存中的位置的结构。 (例如:返回X [NNN]; 而不是的返回X [0]; )。这种方法将使用更多的内存和一些处理零字节填充它。


最后,我正在寻找一个解决方案,将是最快,最干净的(在code而言),从长远来看。如果非要用被卡住 - 方式> 来解决元素的成员,然后我想这是要走的路。

有没有人有使用最少的CPU处理能力的解决方案?

 的#include<&stdio.h中GT;
    #包括LT&;&stdlib.h中GT;
    #包括LT&;&string.h中GT;    typedef结构{
    长;
    炭B:
    } AB;    静逸的char [500];    AB F2(INT组){
      AB * X =(AB *)DAT;
      如果(设置== 2){返回NULL;}
      如果(组== 1){
      的x>一种= 1;
      x轴与GT; B ='1';
      X ++;
      的x>一种= 2;
      x轴与GT; B ='2';
      X =(AB *)DAT;
      }
      返回X [0];
    }    诠释主(){
      ABÿ;
      Y = F2(1);
      的printf(%C,y.b);
      y.b ='D';
      Y = F2(0);
      的printf(%C,y.b);
      返回0;
    }


解决方案

如果你在乎速度,它是特定的实现。

注意,Linux的的x86-64 ABI 定义了一个结构中的两个的(准确)的的成员(即,整数,双打,或指针,哪位都适合在一个单一的机登记册而不是结构等等......这是汇总数据)返回直通两个寄存器(​​而不去THRU栈),这是相当快的。

BTW

 如果(设置== 2){返回NULL;} //错误

显然是错误的。你可以code:

 如果(设置== 2)回报(AA){0,0};

此外,

  AB * X =(AB *)DAT; //可疑

看起来很可疑,我(因为你返回X [0]; 更新版本)。你是不是保证 DAT 对齐适当(如8或16个字节),并在一些平台上(特别是X86-64)如果 DAT 未对准你至少损失性能(实际上,它是未定义行为 )。

顺便说一句,我建议总是像返回指令(AA)返回{L,C}; (其中是一个前pression转换为 C 是一个前pression转换为字符);这可能是最简单的阅读,并进行优化,以装载两个返回的寄存器。

当然,如果你关心性能,基准目的,应启用优化(和警告),例如与的gcc -Wall -Wextra -O2 -march =本地如果使用编译GCC ;我的系统上的小功能。

(Linux的/用GCC 5.2的x86-64)

  AB give_both(长×,焦炭Y)
  {回报(AB){X,Y}; }

编译(用的gcc -O2 -march =本地-fverbose-ASM -S )为:

  .globl give_both
         .TYPE give_both,@function
 give_both:
 .LFB0:
         .file 1ab.c
         1的.loc 7 0
         .cfi_startproc
 .LVL0:
         1的.loc 7 0
         xorl%EDX,EDX%#D.2139
         MOVQ%RDI,RAX%#X,X
         MOVB%SIL,DL%#Y,D.2139
         RET
         .cfi_endproc

您看到所有code使用的寄存器,并没有存储在所有使用。

When I attempt to run this code as it is, I receive the compiler message "error: incompatible types in return". I marked the location of the error in my code. If I take the line out, then the compiler is happy.

The problem is I want to return a value representing invalid input to the function (which in this case is calling f2(2).) I only want a struct returned with data if the function is called without using 2 as a parameter.

I feel the only two ways to go is to either:

  1. make the function return a struct pointer instead of a dead-on struct but then my caller function will look funny as I have to change y.b to y->b and the operation may be slower due to the extra step of fetching data in memory.

  2. Allocate extra memory, zero-byte fill it, and set the return value to the struct in that location in memory. (example: return x[nnn]; instead of return x[0];). This approach will use more memory and some processing to zero-byte fill it.

Ultimately, I'm looking for a solution that will be fastest and cleanest (in terms of code) in the long run. If I have to be stuck with using -> to address members of elements then I guess that's the way to go.

Does anyone have a solution that uses the least cpu power?

    #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;
    }

解决方案

If you care about speed, it is implementation specific.

Notice that the Linux x86-64 ABI defines that a struct of two (exactly) scalar members (that is, integers, doubles, or pointers, -which all fit in a single machine register- but not struct etc... which are aggregate data) is returned thru two registers (without going thru the stack), and that is quite fast.

BTW

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

is obviously wrong. You could code:

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

Also,

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

looks suspicious to me (since you return x[0]; later). You are not guaranteed that dat is suitably aligned (e.g. to 8 or 16 bytes), and on some platforms (notably x86-64) if dat is misaligned you are at least losing performance (actually, it is undefined behavior).

BTW, I would suggest to always return with instructions like return (aa){l,c}; (where l is an expression convertible to long and c is an expression convertible to char); this is probably the easiest to read, and will be optimized to load the two return registers.

Of course if you care about performance, for benchmarking purposes, you should enable optimizations (and warnings), e.g. compile with gcc -Wall -Wextra -O2 -march=native if using GCC; on my system (Linux/x86-64 with GCC 5.2) the small function

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

is compiled (with gcc -O2 -march=native -fverbose-asm -S) into:

         .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

you see that all the code is using registers, and no memory is used at all..

这篇关于从结构功能不兼容的返回类型 - Ç的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆