43

Linux で を使用してこれをコンパイルしようとするとgcc -std=c99、コンパイラはstruct timespec. ただし、これをコンパイルせずにコンパイルすると、-std=c99すべて正常に動作します。

#include <time.h>

int main(void)
{
  struct timespec asdf;
  return 0;
}

これはなぜですか?また、まだ動作させる方法はあり-std=c99ますか?

4

3 に答える 3

60

明示的に POSIX 機能を有効にする

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) からの定義をトリガーします。

  • POSIX 2008 (SUS v4) の素材が必要な場合は、_XOPEN_SOURCE 700
  • POSIX 2004 (SUS v3) の素材が必要な場合は、_XOPEN_SOURCE 600
  • POSIX 1995 (SUS v2, 1997) の素材が必要な場合は、_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 の使用は失敗しました。

GCC は-std=gnuXXオプションを提供します

-std=c11GCC (または GCC をエミュレートする Clang)を指定すると、標準の C 定義のみが有効になります。を使用する-std=gnu11と、標準 C に対する POSIX およびその他の拡張機能がデフォルトで表示されます。

GCC 4.x 以前は-std=gnu90デフォルトで (C90 プラス拡張機能に対応) 使用されていることに注意してください。GCC 5.x 以降では-std=gnu11デフォルトで使用されます。-std=gnu99デフォルトで有効になっている GCC のバージョンはありませんでした。

ヘッダーを使用して POSIX バージョン情報を制御する

私は現在 (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サブディレクトリのファイルとして入手できます。

C11 定義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=c2xstruct timespec

于 2010-10-06T17:24:00.977 に答える
40

でコンパイルすることをお勧めし-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
于 2010-10-06T17:22:57.340 に答える