このメモ 言います:
-ansi
:ANSI言語オプションを実装するようコンパイラーに指示します。これにより、ANSI標準と互換性のないGCCの特定の「機能」がオフになります。
-pedantic
:-ansi
と組み合わせて使用すると、コンパイラにANSI標準に厳密に従うように指示し、準拠していないコードを拒否します。
まず最初に:
-pedantic
および-ansi
オプションの目的は何ですか(上記の説明を理解できませんでした)。GCCコンパイラは、可能な限りプログラムをコンパイルしようとします。ただし、場合によっては、CおよびC++標準では、特定の拡張機能が禁止されていることが指定されています。 gccやg ++などの適合コンパイラは、これらの拡張機能が検出されたときに診断を発行する必要があります。たとえば、gccコンパイラの-pedanticオプションを使用すると、そのような場合にgccが警告を発行します。より厳密な-pedantic-errors
オプションを使用すると、そのような診断警告がエラーに変換され、そのような時点でコンパイルが失敗します。準拠するコンパイラによってフラグを設定する必要がある非ISO構造のみが警告またはエラーを生成します。
私はコーディングで常にそれを使用しています。
-ansi
フラグは-std=c89
と同等です。前述のように、GCCの一部の拡張機能が無効になります。 -pedantic
を追加すると、拡張機能が無効になり、警告が生成されます。たとえば、509文字より長い文字列リテラルがある場合、-pedantic
は、C89標準で必要な最小制限を超えているため、それについて警告します。つまり、すべてのC89コンパイラは、長さ509の文字列を受け入れなければなりません。長い文字列を受け入れることは許可されていますが、つまらない場合は、コンパイラが長い文字列を受け入れることを許可されていても、長い文字列を使用することはできません。
-ansi
は廃止されたスイッチであり、C標準の30年前の古いリビジョン、ISO/IEC 9899:1990、これは本質的にANSI標準のブランド変更ですX3.159-1989 "Programming Language C。なぜ廃止されたのですか?C90がISOによって公開された後、ISOがCの標準化を担当し、C90に対するすべての技術的正誤表がISOで公開されているため、-std=c90
を使用する方が適しています。
このスイッチがなければ、最近のGCC Cコンパイラは、ISO/IEC 9899:2011または最新の2018リビジョンで標準化されたC言語に準拠します。
残念なことに、標準化文書が標準化団体からも入手できない古い時代遅れの標準リビジョンに固執することは容認できると信じている怠zyなコンパイラベンダーがいます。
スイッチを使用すると、これらの廃止されたコンパイラでコードをコンパイルする必要があります。
-pedantic
は興味深いものです。 -pedantic
がない場合、特定の標準が要求された場合でも、GCCはC標準では受け入れられない拡張を許可します。たとえば、プログラムを検討してください
struct test {
int zero_size_array[0];
};
C11ドラフトn1570パラグラフ6.7.6.2p1による :
オプションの型修飾子とキーワードstaticに加えて、[と]は式または*を区切ることができます。式(配列のサイズを指定)を区切る場合、式は整数型でなければなりません。式が定数式である場合、ゼロより大きい値を持たなければなりません。[...]
C標準では、配列の長さをゼロより大きくする必要があります。この段落はconstraintsにあります;標準では次のように書かれています 5.1.1.3p1 :
動作が明示的に未定義または実装として指定されている場合でも、前処理の翻訳単位または翻訳単位に構文規則または制約の違反が含まれる場合、適合実装は少なくとも1つの診断メッセージ(実装定義の方法で識別)を生成するものとします。定義済み。他の状況では診断メッセージを作成する必要はありません。9)
ただし、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が実際に標準の文字に準拠するようにする必要があります。
質問の最後の部分は、-ansi
をC++で使用することでした。 ANSIはC++言語を標準化することはありません-ISOからのみ採用しているため、「フランスで標準化された英語」と言うのと同じくらい理にかなっています。しかし、GCCはC++でそれを受け入れているようです。
基本的には、ANSI標準を実装する他のコンパイラーでのコードのコンパイルがはるかに容易になり、使用するライブラリー/ API呼び出しに注意が必要な場合は、他のオペレーティングシステム/プラットフォームでコードをコンパイルしやすくなります。
1つ目は、GCCの特定の機能をオフにします。 (-ansi)2つ目は、標準に準拠していない(GCCの特定の機能だけでなく、あなたの構成体も)何にも文句を言います(-pedantic)。
コードをportableにする必要がある場合は、gcc拡張機能やその他の非標準機能なしでコンパイルされることをテストできます。コードが-pedantic -ansi
でコンパイルされる場合、理論上は他のANSI標準コンパイラで問題なくコンパイルされるはずです。
想定しているコードを作成する場合、さまざまなコンパイラを使用してさまざまなプラットフォームでコンパイルすることを考えている場合、これらのフラグを自分で使用すると、GCCでのみコンパイルされるコードを生成しないようになります。
他の人は十分に答えています。頻繁に使用される拡張機能の例をいくつか追加します。
main
を返すvoid
関数。これは標準では定義されていません。つまり、一部のコンパイラ(GCCを含む)でのみ機能し、他のコンパイラでは機能しません。ところで、int main()
とint main(int, char**)
は、標準で定義されている2つのシグネチャです。
別の一般的な拡張機能は、他の関数内で関数を宣言および定義できることです。
void f()
{
void g()
{
// ...
}
// ...
g();
// ...
}
これは非標準です。このような動作が必要な場合は、 C++ 11 lambdas を確認してください。
Pedanticは、gccコンパイラがANSI互換にするものだけでなく、すべてのGNU C拡張を拒否するようにします。