GCC / G ++コンパイラで-pedanticを使用する目的は何ですか?


136

このメモは言う:

-ansi:ANSI言語オプションを実装するようコンパイラーに指示します。これにより、ANSI標準と互換性のないGCCの特定の「機能」がオフになります。

-pedantic:と組み合わせて使用​​すると-ansi、ANSI標準に厳密に準拠するようコンパイラーに指示し、準拠していないコードはすべて拒否されます。

まず最初に:

  • GCC / G ++コンパイラの-pedanticおよび-ansiオプションの目的は何ですか(上記の説明を理解できませんでした)?
  • これらの2つのオプションを使用するための適切な状況を誰かに教えてもらえますか?
  • いつ使うべきですか?
  • それらは重要ですか?

回答:


84

GCCコンパイラーは、可能な場合は常にプログラムをコンパイルしようとします。ただし、場合によっては、CおよびC ++標準では、特定の拡張を禁止するように指定しています。gccやg ++などの準拠コンパイラは、これらの拡張機能が検出されたときに診断を発行する必要があります。たとえば、gccコンパイラの-pedanticオプションは、そのような場合にgccに警告を発行させます。stricter -pedantic-errorsオプションを使用すると、 このような診断警告がエラーに変換され、コンパイルが失敗します。警告またはエラーを生成するのは、準拠するコンパイラによってフラグを立てる必要がある非ISO構成だけです。


3
ISO CおよびC ++標準は「拡張を禁止する」だけであり、拡張は準拠プログラムの動作を変更してはなりません。コンパイラーは、拡張機能を使用するプログラムを拒否することを強制されません。
MM

@MM:一部のコンパイラが有用な構造を受け入れ、他のコンパイラがそれを拒否する場合、委員会の「妥協」は、適合実装が診断を発行しなければならないことをプログラマが無視できるようにすることであり、したがって委員会が構成を強制または禁止します。
スーパーキャット

105

私はコーディングでいつもそれを使用しています。

-ansiフラグと等価です-std=c89。前述のように、GCCの一部の拡張機能をオフにします。追加する-pedanticと、拡張機能がオフになり、警告が生成されます。たとえば、509文字より長い文字列リテラルがある場合-pedantic、C89標準で必要な最小制限を超えているため、警告が表示されます。つまり、すべてのC89コンパイラは長さ509の文字列を受け入れる必要があります。長い文字列を受け入れることは許可されていますが、コンパイラーが長い文字列を受け入れることは許可されていて、GCCもそれらを受け入れる場合でも、慣れている場合は長い文字列を使用することはできません。


-ansiはGCCの一部の拡張機能をオフにしますが、-pedanticはさらに拡張機能をオフにします。-ansiが最初のレベルのルールで、次に-pedanticがより制限されたルールのようです。この2つのオプションを削除すると、コードをMicrosoftのような他のコンパイラとより互換性を持つことができるという意味ですか?
huahsin68

4
@ huahsin68:まあ、多かれ少なかれ。MSVCは他のほとんどのものとはかなり異なるコンパイラーであり、特定のエコシステムにより適応しており、外部では利用できません。それは独自の方法で多くのことを行います-これは標準と同じではありません。それでも、標準ヘッダーなどを使用している場合、MSVCとGCCはかなり似ています。ただし、使用-std=c89 -pedanticすると、他のプラットフォーム上の異なるコンパイラ間をより簡単に移動できるようになります。の使用を開始する<windows.h>とすぐに、他のシステムとの互換性に問題が生じます。
ジョナサンレフラー

2
@slf:他のすべてのベンダーと同様に(GNUがコンパイラーを現金で販売していないにもかかわらず)、彼らはあなたが独自の機能を使用することを望んでいますか?または、より一般的には、拡張機能を有用であると見なし、デフォルトで有効にする必要があると考えているためです。
ジョナサンレフラー

1
何のためにそれは価値がある、とJFTRは、私はほとんど使用して停止しました-pedanticが、私はそれ(明示的に使用していたしませんでした一つのプログラム再び有効にするときに私のコードのほとんどはまだOKをコンパイルする__int128タイプの、ある pedantically間違ったを)。GCCが(私の好みでは)騒々しすぎたときに介入段階があったと思います-pedantic。約300のソースファイル(ライブラリコード、コマンド、SOテストプログラム)をテストしたところ、予想される問題が1つだけありました。現在Mac OS X 10.9.2でGCC 4.8.2を使用しています。
ジョナサンレフラー2014年

1
@JonathanLeffler、はい、実際に動作しない実際のコンパイラの名前は何ですか?そのようなコンパイラは1つでもありますか?
Pacerier

23

-ansi30歳に応じてコンパイルするコンパイラを要求時代遅れスイッチであるC標準の時代遅れの改正1990:ISO / IEC 9899、基本的にANSI標準の再ブランドである言語CプログラミングX3.159-1989は、」。なぜ廃止されたのですか?C90がISOによって公開された後、ISOはCの標準化とすべての技術的な修正を担当してきました C90はISOによって公開されたため、を使用する傾向があります-std=c90

このスイッチがない場合、最近のGCC Cコンパイラは、ISO / IEC 9899:2011で標準化されたC言語、または最新の2018リビジョンに準拠します。

残念ながら、一部の遅延コンパイラベンダーの中には、標準化文書が標準化された機関からさえ入手できない、古い廃止された標準リビジョンに固執することは許容できると考えています。

スイッチを使用すると、これらの古いコンパイラでコードを確実にコンパイルできます。


これ-pedanticは興味深いものです。がない-pedantic場合、特定の標準が要求された場合でも、GCCはC標準で受け入れられない一部の拡張を許可します。たとえばプログラムを考えてみましょう

struct test {
    int zero_size_array[0];
};

C11ドラフトn1570段落6.7.6.2p1氏は述べています

オプションの型修飾子とキーワードstaticに加えて、[および]は式または*を区切ることができます。式(配列のサイズを指定する)を区切る場合、式は整数型でなければなりません。式が定数式の場合、その値はゼロより大きい値でなければなりません。[...]

C標準では、配列の長さがゼロより大きいことが要求されています。そしてこの段落は制約の中にあります。標準では、次の5.1.1.3p1と記載されています。

動作が未定義または実装として明示的に指定されている場合でも、前処理変換ユニットまたは変換ユニットに構文規則または制約の違反が含まれている場合、適合実装は少なくとも1つの診断メッセージ(実装定義の方法で識別)を生成します。定義された。他の状況では診断メッセージを生成する必要はありません。

ただし、プログラムをコンパイルすると gcc -c -std=c90 pedantic_test.c、警告は生成されません。

-pedanticコンパイラーが実際にC標準準拠するようにします。そのため、標準で要求されているように、診断メッセージが生成されます。

gcc -c -pedantic -std=c90 pedantic_test.c
pedantic_test.c:2:9: warning: ISO C forbids zero-size array zero_size_array [-Wpedantic]
     int zero_size_array[0];
         ^~~~~~~~~~~~~~~

したがって、最大限の移植性を得るには、標準リビジョンを指定するだけでは不十分であり、使用する必要があります-pedantic(または-pedantic-errors)を使用して、GCCが実際に標準の文字に準拠していることを確認する。


質問の最後の部分は、使用についてだった-ansiC ++。ANSIはC ++言語を標準化したことがなく、ISOから採用しただけなので、これは「フランスで標準化された英語」と同じくらい意味があります。しかし、GCCはそれがC ++の場合はそれを受け入れるように思えます。


4
言語標準がさらに改訂されていることに注意してください。今日、私は通常、でコンパイルし-std=c11 -Wall -Wextra -Wpedantic -Wconversionます。
Davislor '20

14

基本的に、ANSI標準を実装している他のコンパイラーの下でコードをコンパイルするのが非常に簡単になります。また、使用するライブラリー/ API呼び出しに注意を払うと、他のオペレーティングシステム/プラットフォームの下でもコンパイルしやすくなります。

1つ目は、GCCの特定の機能をオフにします。(-ansi)2番目のものは、標準に準拠していないもの(GCCの特定の機能だけでなく、構造も同様です)について不満があります(-pedantic)。


6

コードを移植可能にする必要がある場合は、gcc拡張機能やその他の非標準機能なしでコンパイルできることをテストできます。あなたのコードが-pedantic -ansiそれでコンパイルするなら、理論的には、他のANSI標準コンパイラでコンパイルできます。


4
-pedanticすべての拡張機能をオフにするのではなく、ダブルアンダースコアの要素を残します。したがって、コード-pedantic -ansiがでコンパイルされ、他の実装でコンパイルされる可能性があると思われる場合は、コンパイルされると言う方がより正確かもしれません。
スティーブジェソップ2010年

3
あなたはダブルアンダースコアのものに言及します、この音は面白いです。正確には何を指しているのですか?
huahsin68

1つの例は、gccの「__asm __()」インラインアセンブリコードですが、gccには問題ありませんが、そのコンパイラーが標準に準拠していたとしても、その二重下線はWindowsコンパイラーでは機能しない可能性があります。

3

さまざまなコンパイラを使用して、さまざまなプラットフォームでコンパイルする予定のコードを記述している場合、これらのフラグを自分で使用すると、GCCでのみコンパイルされるコードを生成しないようにするのに役立ちます。


2
GCCの一部のバージョンでは!
Mohamed Amjad LASRI 2017

1

他は十分に答えました。頻繁に使用する拡張機能の例をいくつか追加したいと思います。

main返す関数void。これは標準で定義されていません。つまり、一部のコンパイラ(GCCを含む)でのみ機能し、他のコンパイラでは機能しません。ところで、int main()及びint main(int, char**)標準が定義されない2人の署名です。

もう1つの一般的な拡張機能は、他の関数内で関数を宣言および定義できることです。

void f()
{
    void g()
    {
       // ...
    }

    // ...
    g();
    // ...
}

これは非標準です。この種の動作が必要な場合は、C ++ 11ラムダをチェックしてください


0

Pedanticは、gccコンパイラがANSI互換にする拡張機能だけでなく、すべてのGNU C拡張機能を拒否するようにします。


1
これはとても興味深いです。あなたはGNU C拡張に言及し、それらの拡張はANSI規格にある場合とない場合があります。これに関する詳細情報を入手できますか?それらの適切なリソースはどこで入手できますか?
huahsin68
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.