簡體   English   中英

使用typedef的GCC不兼容指針類型

[英]GCC Incompatible pointer type using a typedef

我有一些在GCC 4.8.4下可以很好編譯的代碼。 我最近升級了系統,現在安裝了GCC 5.2.1,並且收到有關不兼容的指針類型的警告。 我已將問題提取到一個重現該錯誤的小示例中:

typedef const double ConstSpiceDouble;
void foo(const double (*)[3]); 

int main(int argc, char **argv) {
  double a[3][3] = {{1,2,3},{1,2,3},{1,2,3}};

  foo((ConstSpiceDouble (*)[3])a);

  return 0;
}

在實際代碼中,typedef,函數定義和類型強制轉換位於控件之外的庫中,否則我將只修復強制轉換和函數以使其匹配。 這是我從編譯器得到的消息:

$ gcc -Werror -c test.c
test.c: In function ‘main’:
test.c:9:7: error: passing argument 1 of ‘foo’ from incompatible pointer type [-Werror=incompatible-pointer-types]
   foo((ConstSpiceDouble (*)[3])a);
       ^
test.c:4:6: note: expected ‘const double (*)[3]’ but argument is of type ‘const ConstSpiceDouble (*)[3] {aka const double (*)[3]}’
 void foo(const double (*)[3]);
      ^
cc1: all warnings being treated as errors

gcc的注釋尤其令人不安,因為它似乎承認這兩種類型是相同的,但無論如何還是會抱怨。

在這里和其他地方的共識似乎是,GCC正在使用const和typedef做意外的事情。 我不知道意外的情況一定會導致bug,但這是由GCC開發人員確定的。

我通過為函數調用定義一個宏來解決了我的編譯問題,該函數調用修復了庫中不匹配的類型轉換。 我通常不喜歡修改庫的內部結構,但是宏允許我不要觸摸實際的庫頭,而是在自己的代碼中定義它,以便將來對其進行注釋,並且如果可能,對該代碼的測試覆蓋應該是一個合理的預警信號基礎庫的更改方式使宏破壞了工作。

這與其說是“解決”,不如說是“解決”的,但是任何進一步的見解可能都必須來自GCC開發人員。

如果將強制類型'a'鍵入為ConstSpiceDouble,則GCC會對const和typedef進行意外操作,最終類型將變為'const const double'。 您可以在錯誤消息 “ const ConstSpiceDouble”中看到該錯誤 ,它等同於“ const const double”,這是行不通的。

解決方案是在將foo函數參數化為'a'之前說'a'為const double或說'a'為ConstSpiceDouble

typedef const double ConstSpiceDouble;
void foo(const double (*)[3]); 

int main(int argc, char **argv) {

  const double a[3][3] = {{1,2,3},{1,2,3},{1,2,3}};
  // or ConstSpiceDouble a[3][3] = {{1,2,3},{1,2,3},{1,2,3}};

  foo(a);

  return 0;
}

'const'前置似乎是最新版本的gcc的新功能,但是我不確定:(

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM