8

異なるバージョンのgccを使用する2つの異なるマシンでソースコードをコンパイルしています。

cflags c89

-Wall -Wextra -Wunreachable-code -g -m32 -D_DEBUG -O0 -D_LARGEFILE64_SOURCE -D_REETRANT -D_THREAD_SAFE

1つはredhat-4です

gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)
Linux 203_test_server 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux

そして1つはFedora18です

gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8)
Linux localhost.localdomain 3.8.1-201.fc18.x86_64 #1 SMP Thu Feb 28 19:23:08 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

私のfedora18はエラーなしでコンパイルされます。ただし、redhat4マシンではエラーが発生します。

channel.h:35: error: redefinition of typedef ‘channel_t’
internal.h:19: error: previous declaration of ‘channel_t’ was here

エラーは単なる循環的な問題だと思います。ただし、同じコードベースで2つの異なるマシンでコンパイルすると、2つの異なるバージョンのgccを使用して実際に違いが生じますか?

新しいバージョンのコンパイラを使用すると、より厳密になる可能性があるため、より多くのエラーが生成されると考えていました。

これはエラーを解決するための質問ではなく、コンパイラに関する一般的な質問です。

将来これを回避するために設定できるフラグはありますか?たぶん、このバージョンのgccでコンパイルする場合、バージョンに互換性がない場合はこれを行いますか?

4

6 に答える 6

11

ソースコードに含まれているヘッダーによって異なります。外部ライブラリにリンクしている場合は、ソースコードが古いシステムにインストールされているライブラリのバージョンと互換性がない可能性があります。

ソースコードに外部ライブラリヘッダー(Cライブラリを除く)が含まれていない場合は、変更が必要なプリプロセッサディレクティブが存在する可能性があります。

編集:

Googleで検索したところ、カーネルヘッダーからのものであるように見えますchannel_t。2台のマシンでカーネルリリースをかなり離れて使用しています。コードがカーネルヘッダーファイルに依存している場合は、RedHatマシンよりも新しいカーネルバージョンが必要になる可能性があります。コードが何であるか(デバイスドライバーですか?)、またはコードに含まれるファイルを指定していないため、これ以上言うのは難しいです。

于 2013-03-05T15:44:02.713 に答える
5

これは次のようなものです。GCC4.6ではなくGCC4.3で「typedefの再定義」エラーが発生するのはなぜですか。

答えは、このチェックを変更するためにgccが変更されたということです。

http://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=ce3765bf44e49ef0568a1ad4a0b7f807591d6412

言語で定義されているが、悪い習慣と見なされている動作に対する警告は、特定の有用なおよび/または無害なユースケースが警告に含まれているため、厳しすぎると見なされる場合があります。次に、コンパイラ開発者は反対の方法で修正を試みます。つまり、警告の量を減らします。この場合、変更により、2番目の定義がtypedefを別の互換性のあるタイプに変更した場合にのみ、警告が表示されます。

他の現在の例は、発表されたばかりのgcc4.8の-Wshadowです。リリースノートでは、関数名が別の関数名によってシャドウされている場合、-Wshadowは警告を表示しなくなると記載されています。

参照: http: //gcc.gnu.org/gcc-4.8/changes.html

編集:これを回避する方法:定義の1つを削除するか、別のインクルードファイルに移動して他の両方の定義を削除します。

于 2013-03-24T12:26:47.280 に答える
4

異なる結果が得られている2つのシステムでchannel.hとinternal.hの内容を比較します。問題はgccのバージョンではないかと思います。エラーは、一方のシステムにもう一方のシステムよりも新しいバージョンのライブラリと関連するヘッダーファイルがある場合など、時間の経過に伴うこれらのファイルへのコード変更の結果である可能性が高くなります。

于 2013-03-12T08:07:51.057 に答える
1

手始めに、あなたの問題について少し話しましょう。システムが一方のシステムでもう一方のシステムよりもエラーを発生させる最も可能性の高い原因は、コードが同一ではないことだと思います。いくつかのツールまたはdiffコマンドを使用してこれを確認し、コードベースで発生した微妙な変更を探すことができます。通常、そのエラータイプで問題が発生した場合、次のような問題が発生します。

typedef struct Foo* Fooptr;

ヘッダーファイルで、次に:

typedef struct Foo
{
    int bar;
} *Fooptr;

ソースファイル内。つまり、typedefをソースにドロップするだけで、問題ないはずです。探すべきもの。

これが問題である場合問題gccを解決するための2番目のオプションは、同じコンピューター上に複数のバージョンのgccを配置し、オプションgccを介して実行する正確なバージョンを指定することです。-vしたがって、Fedora18マシンで4.1.2を試してみるのは良い考えかもしれません。

別の注意点として、この-vオプションを使用するが、実行するバージョンを指定しないgcc場合、コンパイルの段階を実行するために実行されるコマンドが(stderr出力で)取得されます。これは、何が起こっているのか、各マシンで何が起こっているのかに大きな違いがあるかどうかを確認するのに役立ちます。


では、質問に移りましょう。はい、次の「バージョンX」でコンパイルするためのフラグがありgccます。最初に、__VERSION__事前定義されたマクロconst char *があります。これにより、バージョン番号が返されます。これは非常に便利ですが、gccのドキュメントに次のように記載されています。

特定の形式のコンテンツに依存するべきではありませんが、少なくともリリース番号が含まれていると期待できます。

それにもかかわらず、私は通常、これからの出力の1つの形式しか見ていません。これは"4.6.3"、私のバージョンがである場合のようなものgccです4.6.3-1ubuntu5

gccこれで、コードの一部が特定のバージョンのエラーを引き起こすことがわかっている(または疑われる)場合は__GNUC__、、、__GNUC_MINOR__および__GNUC_PATCHLEVEL__事前定義されたマクロを使用して自分自身を「保護」でき
ます。これを使って:

#if __GNC__ == 3
    printf(“Hello version 3.x.x\n”);
#elif __GNC__ == 4
    printf(“Hello version 4.x.x\n”);
#endif

したがって、バージョンが4.6.3である上記のシステムでは、「Helloversion4.xx」というメッセージが表示されます。次に、より高度になり、subversionsも確認できます。

#if __GNUC__ > 3 || \
    (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \
        (__GNUC_MINOR__ == 2 && \
          __GNUC_PATCHLEVEL__ > 0))
    printf(“I’m a gcc greater than 3.2.0\n”);
#endif

または、独自のマクロを使用したよりクリーンなバージョン:

#define GCC_VERSION (__GNUC__ * 10000 \
    + __GNUC_MINOR__ * 100 \
    + __GNUC_PATCHLEVEL__)
#if GCC_VERSION > 30200
    printf(“I’m a gcc greater than 3.2.0\n”);
#endif

gccのバージョンが異なるとエラーが異なるかどうかについての質問に答えるにgccは、リリースごとにさらに多くのことが行われ、場合によっては状況が変わるため、コンパイラのバージョンが異なると違いがわかります。最善の策は、使用している2つのバージョン間の各バージョンのリリースノートを確認することです。(4.1から4.7へ)。

使用しているターゲットアーキテクチャがわからないため、各ドキュメントの特定のセクションを確認してください。しかし、あなたは本当にとを見てみたいと思います。"Build system improvements"それら"Incompatible changes to the build system"はまた、レビューするのに便利なCコードに固有のセクションを作成します。

于 2013-03-22T12:46:49.907 に答える
1

ここには、何が起こっているのかを正確に伝えるのに十分な情報がありません。コンパイラのバージョンの問題ではないだろうと言う人たちと一緒に参加します。

このエラーは、コンパイラーが同じ名前に対して2つの異なる宣言を検出したときに(明らかに)発生します。なぜこれが起こっているのかを理解するのはそれほど難しいことではありません。

makefileをチェックして、参照されているヘッダーファイルinternal.hchannel.hヘッダーファイルを見つけます。引用された行には、typedefまたは他の宣言がchannel_tあります。手がかりを得るために、これらの宣言から外側に向かって作業します。

これらのファイルの一方または両方が、使用しているライブラリにあると想定する必要があります。internal.hとが両方とも独自のコードである場合channel.hは、独自のコードをデバッグしてください。

そうでなければ、多くの可能性があります。最も可能性が高いのは

  1. プリプロセッサ-Dまたは#defineedフラグが正しくないため、1つだけが必要なときに、複数の宣言が条件付きでコンパイルされます。

  2. 2つの異なるライブラリ、または標準ヘッダーとライブラリの名前が衝突しています。

  3. 独自のコードは、ライブラリまたは標準ヘッダーと衝突します。channel_tが定義したタイプの場合、それは問題です。_tこれらは実装用に予約されているため、で終わる独自のタイプを定義しないでください。

上記の1はいくつかの方法で発生する可能性がありますが、最も一般的なのはライブラリの設定ミスです。ライブラリは通常、./configure使用しているOSに合わせて編集する必要があります。あるLinuxで構成し、別のLinuxにコピーすると、発生しているような問題が発生します。

2番目は、ライブラリのバージョンの違いにより、一方のLinuxで発生する可能性があり、もう一方のLinuxでは発生しない可能性があります。この場合、エラーのあるマシンをエラーのないマシンと同じバージョンに更新してください。実行することを忘れないでください./configure

番号3の場合、修正は明らかです。タイプ名を変更します。

Torにとが表示channel.hされます。channel_t私の大げさな推測は、あなたがTorを使用していて、エラーのあるマシンでTorの設定ミスを見ているということです。

于 2013-03-22T17:02:12.720 に答える
1

これはエラーを解決するための質問ではなく、コンパイラに関する一般的な質問です。

将来これを回避するために設定できるフラグはありますか?

コンパイラの特定のバージョンには、それぞれ独自のスイッチまたはフラグが付属しています。

コンパイラバージョンが特定のスイッチを受け入れるように作成されており、そのうちの1つがソースコードの特定のチェックを回避する必要がある場合は、将来的にそれを回避する方法があります。

使用しているコンパイラバージョン(最近または将来のバージョン)に、ソースコードの特定のチェックを回避/スキップするためのスイッチがない/受け入れられない場合、それを回避する方法はありません。

于 2013-03-27T15:03:24.413 に答える