簡體   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