struct function的不兼容返回类型 – C.

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

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

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

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

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

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

有没有人有一个使用最少的CPU功率的解决方案?

  #include  #include  #include  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",yb); yb='D'; y=f2(0); printf("%c",yb); return 0; } 

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

请注意,Linux x86-64 ABI定义了两个 (完全) 标量成员的结构(即整数,双精度或指针,它们都适合单个机器寄存器 – 但不是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}; (其中l是可转换为long的表达式, c是可转换为char的表达式); 这可能是最容易阅读的,并且将被优化以加载两个返回寄存器。

当然,如果你关心性能,为了进行基准测试,你应该启用优化(和警告),例如使用gcc -Wall -Wextra -O2 -march=native编译,如果使用GCC ; 在我的系统(Linux / x86-64与GCC 5.2)上的小function

  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