Linux で を使用してこれをコンパイルしようとするとgcc -std=c99
、コンパイラはstruct timespec
. ただし、これをコンパイルせずにコンパイルすると、-std=c99
すべて正常に動作します。
#include <time.h>
int main(void)
{
struct timespec asdf;
return 0;
}
これはなぜですか?また、まだ動作させる方法はあり-std=c99
ますか?
timespec は POSIX に由来するため、POSIX 定義を「有効」にする必要があります。
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE 500
#endif /* __STDC_VERSION__ */
#include <time.h>
void blah(struct timespec asdf)
{
}
int main()
{
struct timespec asdf;
return 0;
}
一番上のスタンザは、私が現在使用しているものです。これは、C99 または C89 コンパイラを使用しているかどうかに基づいて、Single UNIX Specification (SUS) からの定義をトリガーします。
_XOPEN_SOURCE 700
_XOPEN_SOURCE 600
_XOPEN_SOURCE 500
コメントに記載されているように、_XOPEN_SOURCE
厳密に使用すると、厳密な POSIX よりも XSI (X/Open System Interface) 拡張機能が有効になりますが、XSI ではなく POSIX が必要になることは非常にまれです。通常は を指定_XOPEN_SOURCE
し、futz ではありません_POSIX_C_SOURCE
。機能マクロの詳細については、コンパイル環境の(POSIX 2018) を参照してください。
2010 年の私のシステムでは、POSIX 2008 は POSIX 2004 ほど広くは利用できなかったので、それを使用しましたが、YMMV を使用しました。SUS v3 と v4 の両方で C99 コンパイルが必要であることに注意してください。Solaris では、少なくとも C89 の使用は失敗しました。
-std=gnuXX
オプションを提供します-std=c11
GCC (または GCC をエミュレートする Clang)を指定すると、標準の C 定義のみが有効になります。を使用する-std=gnu11
と、標準 C に対する POSIX およびその他の拡張機能がデフォルトで表示されます。
GCC 4.x 以前は-std=gnu90
デフォルトで (C90 プラス拡張機能に対応) 使用されていることに注意してください。GCC 5.x 以降では-std=gnu11
デフォルトで使用されます。-std=gnu99
デフォルトで有効になっている GCC のバージョンはありませんでした。
私は現在 (2019 年) ヘッダーを使用してこの情報をカプセル化しているため、将来の変更では、POSIX 機能を使用するすべてのソース ファイルではなく、単一のヘッダーのみを変更する必要があります。時が経ち、POSIX 2008 が普及するにつれて、複数のソース ファイルから古いスタンザを編集するのは苦痛でした。
/*
@(#)File: $RCSfile: posixver.h,v $
@(#)Version: $Revision: 1.4 $
@(#)Last changed: $Date: 2017/06/18 00:15:42 $
@(#)Purpose: Request appropriate POSIX and X/Open Support
@(#)Author: J Leffler
@(#)Copyright: (C) JLSS 2010-2017
*/
/*TABSTOP=4*/
#ifndef JLSS_ID_POSIXVER_H
#define JLSS_ID_POSIXVER_H
/*
** Include this file before including system headers. By default, with
** C99 support from the compiler, it requests POSIX 2008 support. With
** C89 support only, it requests POSIX 1997 support. Override the
** default behaviour by setting either _XOPEN_SOURCE or _POSIX_C_SOURCE.
*/
/* _XOPEN_SOURCE 700 is loosely equivalent to _POSIX_C_SOURCE 200809L */
/* _XOPEN_SOURCE 600 is loosely equivalent to _POSIX_C_SOURCE 200112L */
/* _XOPEN_SOURCE 500 is loosely equivalent to _POSIX_C_SOURCE 199506L */
#if !defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE)
#if defined(__cplusplus)
#define _XOPEN_SOURCE 700 /* SUS v4, POSIX 1003.1 2008/13 (POSIX 2008/13) */
#elif __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 700 /* SUS v4, POSIX 1003.1 2008/13 (POSIX 2008/13) */
#else
#define _XOPEN_SOURCE 500 /* SUS v2, POSIX 1003.1 1997 */
#endif /* __STDC_VERSION__ */
#endif /* !_XOPEN_SOURCE && !_POSIX_C_SOURCE */
#endif /* JLSS_ID_POSIXVER_H */
Stack Overflow で使用される「CC by-sa 3.0」ライセンスで通常要求される帰属および著作権表示なしで、このヘッダーの情報を使用できます。このコードは、GitHubのSOQposixver.h
(Stack Overflow Questions) リポジトリで、src/libsoqサブディレクトリのファイルとして入手できます。
struct timespec
C11ではstruct timespec
が定義されており、POSIX (最初に定義された) と互換性のある方法で定義されていることに注意してください。
ヘッダー<time.h>
はタイプを定義します。それを使用する 3 つの関数は in で宣言され<threads.h>
、もう 1 つは in で宣言され<time.h>
ます。
もちろん、これらはC17(C18)の一部でもあります。タイプが自動的に定義されるようにするには、または類似のものをコンパイルする必要があり-std=c11
ます(GCC 9.2.0は、標準の次のバージョンの-std=c17
と-std=c18
、およびの両方を認識するようです)。-std=c2x
struct timespec
でコンパイルすることをお勧めし-std=gnu99
ます。
これについて詳しく説明します。デフォルトでは、gcc は -std=gnu89 でコンパイルされます。以下は、次のソース コードの結果です。
#include <time.h>
int main() {
struct timespec asdf;
return 0;
}
[1:25pm][wlynch@cardiff /tmp] gcc -std=gnu89 foo.c
[1:26pm][wlynch@cardiff /tmp] gcc -std=gnu99 foo.c
[1:25pm][wlynch@cardiff /tmp] gcc -std=c89 foo.c
foo.c: In function ‘main’:
foo.c:4: error: storage size of ‘asdf’ isn’t known
[1:26pm][wlynch@cardiff /tmp] gcc -std=c99 foo.c
foo.c: In function ‘main’:
foo.c:4: error: storage size of ‘asdf’ isn’t known