Ccの現在のバージョンを確認するように依頼すると、これが表示されます。
$ cc --version
cc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$
私が知りたいのは、c89、c90、c99、c11のどれが使用されているかです。
これはgccマニュアルで詳しく説明されており、info gcc
またはonline here と入力することで利用できます(インストールされている場合)。 4.7.2マニュアルの関連セクションは、 here です。
デフォルトでは、gccはANSI/ISO C標準のいずれにも準拠していません。現在のデフォルトは-std=gnu90
と同等です。これは、GNU固有の拡張機能を備えた1989/1990標準です。 (言語標準で必要な診断の一部は発行されていません。)バージョン5.1.0、2015年4月22日リリース、デフォルトを-std=gnu90
から-std=gnu11
に変更しました ここに文書化されています 。
標準準拠が必要な場合は、次のいずれかを使用できます。
-std=c90 -pedantic
-std=c99 -pedantic
-std=c11 -pedantic
-std=c90
は、-ansi
、-std=c89
、または-std=iso9899:1990
と綴ることもできます。
-std=iso9899:199409
は、C90標準に加えて、いくつかのマイナーな機能を追加した1995年の修正をサポートしています(すべてC99にもあります)。
-std=c99
は、-std=c9x
または-std=iso9899:1999
(標準が公開される前にc9x
という名前が使用されていました)のスペルも使用できます。 C99サポートは 完全ではありません が、近いです。
-std=c11
は、-std=c0x
または-std=iso9899:2011
(最終標準が公開される前にc0x
という名前が使用されていましたが、x
は9を超える)。 C11のサポートも不完全です。現在のステータスは、 ここに要約されています 。
-pedantic
オプションを使用すると、gccは制約と構文規則の違反について必要な診断を出力します。場合によっては、それらの診断は単なる警告であり、これらの警告と言語で必要のない他の警告を区別する簡単な方法はありません。 -pedantic
を-pedantic-errors
に置き換えて、gccが言語違反を致命的なエラーとして扱うようにします。
標準の簡単な歴史:
__STDC_VERSION__
および__STDC_LIB_EXT1__
の定義を修正する技術的な正誤表が1つありました。ANSIは、独自のバージョンの1999または2011標準を発行せず、代わりにISO標準を採用しました。
N1256 は、C99標準の自由に利用可能なドラフトであり、3つの技術的正誤表がマージされています。
N1570 は、C11標準の自由に利用可能なドラフトです。公開されているC11標準と技術的な正誤表に加えて、いくつかの小さな違いがあります。詳細については、 my answer to this question を参照してください。
info gcc
gcc6の場合 https://gcc.gnu.org/onlinedocs/gcc-5.4.0/gcc/Standards.html#Standards gcc5の場合
6.3.1
-7.3.1
2.1 C Language
==============
The default, if no C language dialect options are given, is
'-std=gnu11'.
2.2 C++ Language
================
The default, if no C++ language dialect options are given, is
'-std=gnu++14'.
5.4.0
2.1 C Language
==============
The default, if no C language dialect options are given, is -std=gnu11
2.2 C++ Language
================
The default, if no C++ language dialect options are given, is -std=gnu++98
Cの場合、デフォルトモードはstd = gnu11のままですが、C++の場合はstd = gnu ++ 98からstd = gnu ++ 14にジャンプしました
最小限のテストプログラム
マニュアルを読まずに経験的に見つけたい場合。
c.c
#include <stdio.h>
int main(void) {
#ifdef __STDC_VERSION__
printf("__STDC_VERSION__ = %ld \n", __STDC_VERSION__);
#endif
#ifdef __STRICT_ANSI__
puts("__STRICT_ANSI__");
#endif
return 0;
}
でテストする:
#!/usr/bin/env bash
for std in c89 c99 c11 c17 gnu89 gnu99 gnu11 gnu17; do
echo $std
gcc -std=$std -o c.out c.c
./c.out
echo
done
echo default
gcc -o c.out c.c
./c.out
結果:
c89
__STRICT_ANSI__
c99
__STDC_VERSION__ = 199901
__STRICT_ANSI__
c11
__STDC_VERSION__ = 201112
__STRICT_ANSI__
c17
__STDC_VERSION__ = 201710
__STRICT_ANSI__
gnu89
gnu99
__STDC_VERSION__ = 199901
gnu11
__STDC_VERSION__ = 201112
gnu17
__STDC_VERSION__ = 201710
default
__STDC_VERSION__ = 201710
結論:gnu17
はデフォルトで使用されます:
__STRICT_ANSI__
:-std=c
に対しては定義されているが-std=gnu
に対しては定義されていないGCC拡張、参照: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined- Macros.html__STDC_VERSION__
:各バージョンに設定されるC99 + ANSI Cマクロ。標準ではまだ定義されていないC89には存在しません。C++
main.cpp
#include <iostream>
int main(void) {
#ifdef __cplusplus
std::cout << __cplusplus << std::endl;
#endif
#ifdef __STRICT_ANSI__
std::cout << "__STRICT_ANSI__" << std::endl;
#endif
return 0;
}
でテストする:
#!/usr/bin/env bash
for std in c++98 c++11 c++14 c++17 gnu++98 gnu++11 gnu++14 gnu++17; do
echo $std
g++ -std=$std -o cpp.out cpp.cpp
./cpp.out
echo
done
echo default
g++ -o cpp.out cpp.cpp
./cpp.out
結果:
c++98
199711
__STRICT_ANSI__
c++11
201103
__STRICT_ANSI__
c++14
201402
__STRICT_ANSI__
c++17
201703
__STRICT_ANSI__
gnu++98
199711
gnu++11
201103
gnu++14
201402
gnu++17
201703
default
201402
結論:gnu++14
がデフォルトです:
__cplusplus
:C++ 98以降を含むC++標準で定義されたマクロUbuntu 18.10、GCC 8.2.0でテスト済み。 GitHubアップストリーム 。
最初の行はGCCバージョン(4.7.2)を示します
(Ubuntu/Linaro 4.7.2-2ubuntu1)4.7.2
コードをコンパイルするときに、-std=c99
または-std=c99
を追加して、使用するC/C++リビジョンを指定できます。
注gnu89
はデフォルトで使用されます。
注意すべきことの1つは、gccの-std =オプションを使用して、標準Cの以降のバージョンのコンストラクトをサポートしないようコンパイラーを「サンドボックス」することはできません。これは、-pedantic
いくつかのC99コード構造を使用してコンパイルしようとすると、gcc -std=c89 -pedantic
に依存してエラーまたは警告を出すことはできません。場合によっては、そうでないこともあります。たとえば、C99まで追加されなかったにもかかわらず、printf()呼び出しで%zu
形式指定子を使用するコードを喜んでコンパイルします。