web-dev-qa-db-ja.com

現在のgcc(特にUbuntu)のデフォルトのCモードは何ですか?

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のどれが使用されているかです。

49
ncmathsadist

これは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が言語違反を致命的なエラーとして扱うようにします。

標準の簡単な歴史:

  • C89は、1989年に [〜#〜] ansi [〜#〜] によって公開された最初の公式C標準でした。
  • C90は [〜#〜] iso [〜#〜] バージョンの標準で、C89とまったく同じ言語を記述していました。 ANSIは、ISOの標準バージョンを公式に採用しました。技術的な正誤表が2つあり、いくつかのエラーを修正しました。
  • C95はC90を修正したもので、主に有向グラフとワイドキャラクターのサポートといういくつかの機能が追加されました。私の知る限り、マージされたバージョンは公開されていません。
  • C99は1999年にISOによって発行されました。3つの技術的正誤表がありました。
  • C11は2011年にISOによって発行されました。__STDC_VERSION__および__STDC_LIB_EXT1__の定義を修正する技術的な正誤表が1つありました。

ANSIは、独自のバージョンの1999または2011標準を発行せず、代わりにISO標準を採用しました。

N1256 は、C99標準の自由に利用可能なドラフトであり、3つの技術的正誤表がマージされています。

N1570 は、C11標準の自由に利用可能なドラフトです。公開されているC11標準と技術的な正誤表に加えて、いくつかの小さな違いがあります。詳細については、 my answer to this question を参照してください。

62
Keith Thompson

info gcc gcc6の場合 https://gcc.gnu.org/onlinedocs/gcc-5.4.0/gcc/Standards.html#Standards gcc5の場合

gccバージョン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'.

gccバージョン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にジャンプしました

15
Varun Garg

最小限のテストプログラム

マニュアルを読まずに経験的に見つけたい場合。

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はデフォルトで使用されます。

3
ablm

注意すべきことの1つは、gccの-std =オプションを使用して、標準Cの以降のバージョンのコンストラクトをサポートしないようコンパイラーを「サンドボックス」することはできません。これは、-pedantic

いくつかのC99コード構造を使用してコンパイルしようとすると、gcc -std=c89 -pedanticに依存してエラーまたは警告を出すことはできません。場合によっては、そうでないこともあります。たとえば、C99まで追加されなかったにもかかわらず、printf()呼び出しで%zu形式指定子を使用するコードを喜んでコンパイルします。

0
Randy Howard