Armadilloフォーラム

C言語のバージョンについて

fukasawa

2019年4月16日 15時48分

お世話になっております。

Armadillo実践開発ガイドを参考にC言語のプログラミングを習得中です。

ガイドではコンパイルは'gcc'または'arm-linux-gnuebi-gcc'が使用されていますが、言語オプション'-std=C99'などは指定されていません。
'gcc'は'-std=gnu11'は認識されましたが、'-std=c11'は認識されませんでした。
'arm-linux-gnuebi-gcc'は両オプションとも認識されませんでした。

そこでC言語のバージョンについて質問があります。

・できればC11、それでなくてもC99を使用したいのですが、それはATDE上でコンパイル可能なのでしょうか。
・言語バージョンを指定することで実行環境の制限など何かデメリットはありますでしょうか。

環境は以下のとおりです。
- Armadillo-440
- Windows10 1803 64bit
- Intel Corei7
- VMware Workstation Player Ver 15.0.2
- ATDE5 amd64

よろしくおねがいします。

コメント

at_mizo

2019年4月16日 17時04分

溝渕です。

> ・できればC11、それでなくてもC99を使用したいのですが、それはATDE上でコンパイル可能なのでしょうか。

ATDE5のgccバージョンはv4.6です。--std=c11オプションが追加されたのは
v4.7なので対応前のバージョンになります。

https://stackoverflow.com/questions/16256586/how-to-enable-c11-on-later…

以下の規格が利用可能です。"c99"が利用可能です。"gnu1x"は、c11のドラフト版になります。

atmark@atde5:~$ arm-linux-gnueabi-gcc -v --help 2>/dev/null | grep -E "^\s+\-std=.*$"
-std= Assume that the input sources are for
-std=f2003 Conform to the ISO Fortran 2003 standard
-std=f2008 Conform to the ISO Fortran 2008 standard
-std=f95 Conform to the ISO Fortran 95 standard
-std=gnu Conform to nothing in particular
-std=legacy Accept extensions to support legacy code
-std=c++03 Conform to the ISO 1998 C++ standard revised by
-std=c++0x Conform to the ISO 1998 C++ standard, with
-std=c++98 Conform to the ISO 1998 C++ standard revised by
-std=c1x Conform to the ISO 201X C standard draft
-std=c89 Conform to the ISO 1990 C standard
-std=c90 Conform to the ISO 1990 C standard
-std=c99 Conform to the ISO 1999 C standard
-std=c9x Deprecated in favor of -std=c99
-std=gnu++0x Conform to the ISO 1998 C++ standard, with GNU
-std=gnu++98 Conform to the ISO 1998 C++ standard with GNU
-std=gnu1x Conform to the ISO 201X C standard draft with GNU
-std=gnu89 Conform to the ISO 1990 C standard with GNU
-std=gnu90 Conform to the ISO 1990 C standard with GNU
-std=gnu99 Conform to the ISO 1999 C standard with GNU
-std=gnu9x Deprecated in favor of -std=gnu99
-std=iso9899:1990 Conform to the ISO 1990 C standard
-std=iso9899:199409 Conform to the ISO 1990 C standard as amended in
-std=iso9899:1999 Conform to the ISO 1999 C standard
-std=iso9899:199x Deprecated in favor of -std=iso9899:1999

> ・言語バージョンを指定することで実行環境の制限など何かデメリットはありますでしょうか。

言語の規格の指定なので、多分バイナリには影響しないのではないかと思います。
# 想像ですみません

fukasawa

2019年4月16日 17時43分

迅速な回答ありがとうございました。

> 以下の規格が利用可能です。"c99"が利用可能です。"gnu1x"は、c11のドラフト版になります。
了解しましたC99を使用いたします。

少し話が違うのですが、'-std=gnu99'は'-std=c99'にGNU拡張を加えたものらしいのですが、
実践開発ガイドの中の'dispcsv1.c'、ではどちらでもコンパイルでき、'serial_echo_server3'では'-std=gnu99'のみコンパイルできます。

そこで2点質問です。
・この差はどこから発生しているのでしょうか。
・この'-std=gnu99'のGNU拡張とは実践開発ガイドの中の`dispcsv1'のGNU拡張関数とは異なるのでしょうか。

よろしくおねがいします。

at_hanada

2019年4月23日 17時10分

> 少し話が違うのですが、'-std=gnu99'は'-std=c99'にGNU拡張を加えたものらしいのですが、
> 実践開発ガイドの中の'dispcsv1.c'、ではどちらでもコンパイルでき、'serial_echo_server3'では'-std=gnu99'のみコンパイルできます。
>
> そこで2点質問です。
> ・この差はどこから発生しているのでしょうか。
> ・この'-std=gnu99'のGNU拡張とは実践開発ガイドの中の`dispcsv1'のGNU拡張関数とは異なるのでしょうか。

より新しいバージョンのgcc(手元の実験では6.3.0)でも同様で、--std=c99指定時はこうなりますね。

$ gcc --std=c99 serial_echo_server3.c
serial_echo_server3.c: In function ‘set_sig_handler’:
serial_echo_server3.c:49:20: error: storage size of ‘sa’ isn’t known
   struct sigaction sa;
                    ^~
serial_echo_server3.c:58:9: warning: implicit declaration of function ‘sigaction’ [-Wimplicit-function-declaration]
     if (sigaction(sig_list[i], &sa, NULL) < 0)
         ^~~~~~~~~
serial_echo_server3.c: In function ‘setup_serial’:
serial_echo_server3.c:99:9: warning: implicit declaration of function ‘cfsetspeed’ [-Wimplicit-function-declaration]
   ret = cfsetspeed(&tio, SERIAL_BAUDRATE); /* 入出力ボーレート */
         ^~~~~~~~~~

struct sigactionでビルド時にエラーが理由は、ヘッダのinclude関係と内部定義が複雑で説明しずらいのですが。
これが発生する理由は、直接的にはC99とPOSIX/各UNIX/Linux互換性に関係します。

C99及びPOSIXではsignal(2)が定義されていますが、これの動作は(歴史的経緯上)UNIXの種類によってまちまちで、Linuxの各バージョン間ですら異なっており「使用自体が危険」とされています。man 2 signalに記載があるはずです。

そこで代替として推奨されているsigaction(2)を、serial_echo_server3.cでは使用しています。Linuxでは当然の記法ということになりますが、これはC99には存在しません。

signal(2): ANSI C signal handling - Linux man page
https://linux.die.net/man/2/signal
> Conforming To
> C89, C99, POSIX.1-2001.

sigaction(2): examine/change signal action - Linux man page
https://linux.die.net/man/2/sigaction
> Conforming To
> POSIX.1-2001, SVr4.

--std=c99を指定するということは(signal機構も含めて)厳密にC99準拠のみで使うことを表明することであり、それはLinuxの一部の機能が使えないということになります。--std=gnu99であれば(sigactionを含めたC99外の)POSIX/Linux機能を使用することができます。この違いです。

fukasawa

2019年4月17日 18時48分

回答ありがとうございました。了解いたしました。

> --std=gnu99であれば(sigactionを含めたC99外の)POSIX/Linux機能を使用することができます

'-std=gnu99'を使用していきます。

よろしくおねがいします。