2015-10-27 25 views
8

GCC 4.8.4でコンパイルしたコードがあります。私は最近システムをアップグレードしてGCC 5.2.1を持っていますが、互換性のないポインタ型についての警告を受けています。私は、エラーを再現する小さな例に問題点を抽出しました:実際のコード、typedefで、関数定義、および型キャストでGCC互換性のないポインタ型(typedefを使用)

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

がそうでなければ私のコントロール外の図書館にいる私がするのと同じキャストとその機能を修正してください。ここで私は、コンパイラから取得するメッセージだ:二つのタイプが同一であることを認めているようですので、GCCから

$ 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 

ノートは特に厄介である、まだそれはとにかく文句を言います。

+4

[GCC 5.2.0](http://coliru.stacked-crooked.com/a/f7768e128db5462b)(およびClang 3.7.0も)にヒッチなしでコンパイルします。私はコンパイラのバグに傾いています。 – Quentin

+0

これは5.2.0でコンパイルされていることを知っておいて、バージョンの可能性を5.2.1に制限しています。 – Gravatite

+0

「5.2.1」と言ったらどういう意味ですか?このバージョンでは、まだ正式にはリリースされていない: ''のsvn:URL 'のsvn://gcc.gnu.org/svn/gcc/tags/gcc_5_2_1_releaseは' –

答えて

2

ここと他のところでは、GCCがconstとtypedefで予期せぬことをしているようですが、予期せぬことは必然的にバグと同じであることを知っていますが、これはGCCの開発者が決定するためのものです。

コンパイルの問題を解決するために、ライブラリ内にある不一致の型変換を修正する関数呼び出し用のマクロを定義しました。私は一般的にはライブラリの内部構造を調べるのが嫌いですが、マクロでは実際のライブラリヘッダに触れず、自分のコードで定義して将来のコメントができる場所にして、そのコードのテスト範囲を合理的な早期警告信号にする必要があります基礎となるライブラリは、マクロが何かを破壊するように変化します。

これは「回避」されているわけではありませんが、それ以上の洞察はGCCの開発者から来る必要があります。

+0

私はそのマクロの抜粋 – hewi

1

キャスト 'a'をConstSpiceDoubleにすると、GCCはconstとtypedefで予期せぬことをしています。これによって最終的に型は 'const const double'になります。これはエラーメッセージ "const ConstSpiceDouble"に相当します。これは 'const const double'に相当しますが、これは機能しません。

ソリューションは「」であると言うことのいずれかであるのconst doubleまたはあなたが「」「のconst」が事前保留思わfooの機能

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

にパラメータの前に「」ConstSpiceDoubleであると言ってgccの最新バージョンの新機能ですが、それはわかりません:(

+0

残念ながら、実際のコードでは、 'a'はそれ自体がconstになることはできません。なぜなら、行列が以前に設定されているように変更されるからです – Gravatite

+2

この回答の最初の段落は間違っていますが、C言語では "自動前保留"はありません。しかし、提案された代替コードはコンパイルされますがOPがconstでないように 'main'の配列を必要とするので、助けにならない –

+0

は"自動prepending "部分を取り出しました – hewi

関連する問題