gcc (GCC) 4.6.3
c89
usleep
を使用しようとしています。ただし、次の警告が引き続き表示されます。
関数usleepの暗黙的な宣言
unistd.h
ヘッダーファイルを含めました。
マニュアルページには、これに関する何かが記載されています。しかし、私はそれで理解できるかどうかわかりません:
usleep():
Since glibc 2.12:
_BSD_SOURCE ||
(_XOPEN_SOURCE >= 500 ||
_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) &&
!(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
Before glibc 2.12:
_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
しかし、私が上記で何をすべきかわからないのですか?
そのリストは、usleep
を定義するための前提条件です。これは基本的に、ヘッダーファイルをインクルードする前にtrueでなければならない#define
変数を含むCのような式です。
ヘッダーファイル自体は、通常#ifdef
ステートメントの大規模なネスト内にあるusleep
のみを定義し、開発者は、あなたがする必要がないことをあなたに伝えるために時間をかけましたあなた自身でそれを理解しようと何時間も費やします:-)
glibc
2.12以上を使用していると仮定すると、次のいずれかを行う必要があります。
おそらく最も簡単な解決策は、単にgcc -D _BSD_SOURCE
でコンパイルするか、
#define _BSD_SOURCE
usleep
を提供するヘッダーファイルをインクルードする前のコードで。
さまざまなヘッダーファイル間に依存関係がある場合に備えて、anyを含める前にこれらを定義することをお勧めします。
これは動作する可能性があります:Linuxでgccを使用してコンパイルする場合、-std=gnu99
を追加します。
例:
arm-linux-gcc -lpthread -std=gnu99 -o test ArmLinuxDataPipe1.2.1.c
usleep()
を使用してコンパイルするレガシーコードを取得する必要がある場合は、他のライブラリの前にインクルードするヘッダーファイルに次の行を追加します。
#define _XOPEN_SOURCE 600
#define _POSIX_C_SOURCE 200112L
または、コンパイラフラグ-std=c11 -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L
をメイクファイルに追加します。
これは、プログラムが この古いバージョンのUNIX API を使用し、usleep()
が非推奨ではなかったことを環境に伝えます。
あるいは、これが新しいコードである場合は、間違いなく、usleep()
を nanosleep()
に置き換え、ライブラリのバージョンに合わせて機能テストマクロを設定し、他のビットの腐敗については、コードベースを確認してください。
Linuxでは、ライブラリが_XOPEN_SOURCE
でサポートしている_POSIX_C_SOURCE
およびman feature_test_macros
の値を確認できます。
より長い答え:これが何が起こっているかです。
歴史的にはいくつかの異なるUNIX標準があり、誰もがヒットした最終的なベストプラクティスは、コードがそれが記述されたUNIX APIのバージョンを指定することでした。プログラマは、機能テストマクロを定義することでこれを行いました。
UNIXの初期の分割の1つは、AT&TのSystem Vとカリフォルニア大学のBerkeley Standard Distribution(BSD)の間でした。 System Vは公式バージョンであり、その動作がデフォルトになったため、BSD Unixは初期のフリーソフトウェアであり、多くの大学で使用されていたため、レガシーコードが_BSD_SOURCE
よりも_SVID_SOURCE
を宣言するのがはるかに一般的です。 _BSD_SOURCE
マクロは、特に40年以上にわたってさまざまなオペレーティングシステムの拡張機能を有効にしようとします。非標準の拡張機能のキャッチオールとして使用されることもあります。両方のマクロは非推奨であり、現在受け入れられている答えとは反対に、新しいコードではどちらも使用しないでください。
今世紀には、IEEE標準となったPOSIXとOpen Group(X/Open)のSingle Unix Specification(SUS)の2つのUNIX標準がありました。 X/Open SUSは、POSIXのスーパーセットであり、通常は何を記述しますか。以前は、次のバージョンを有効にするために宣言できるさまざまな機能テストマクロがありました。これらの標準は、下位互換性のために引き続きサポートされています。貼り付けた条件でそれらの一部を確認できますが、新しいコードを記述するときにそれらを心配する必要はありません。コードをチェックするマクロは、_XOPEN_SOURCE_EXTENDED
です。時代遅れですが、歴史的に1995年からSUSのバージョンを選択しました。
理論的には、UNIXまたはLinuxの最新バージョンで設定する正しい機能テストマクロは_XOPEN_SOURCE
です。ライブラリがサポートしている最新のバージョン番号を調べる必要があります。実際には、_POSIX_C_SOURCE
も定義して、他の誰も一貫性のない設定をしてコードを破ることができないように保証するのが賢明な防御コーディングだと思います。あなたの質問は良い例です:後方互換性のために_XOPEN_SOURCE
を設定しても、_POSIX_C_SOURCE
がツールチェーンの他の場所でより新しいバージョンに設定される場合、_POSIX_C_SOURCE
の上位バージョンが優先され、usleep()
は機能しません。
したがって、これらの条件が意味するのは、usleep()
はPOSIX関数ではなく、一部のBSD系OSに一度存在したため、SUS 1995年に廃止されました。2008年に廃止され、POSIXの任意のバージョンまたはSUSを選択すると、それがアクティブに無効になります。したがって、SUS(および他の古い同義語もオンにします)、しかし、POSIXまたはSUSの最新バージョンを選択した場合は非推奨です。anything-goesオプションを選択した場合も有効になりますが、それは悪いことです考え。
コードの先頭に次を追加します。
_// For `nanosleep()`:
#include <time.h>
#define __USE_POSIX199309
#define _POSIX_C_SOURCE 199309L
_
そして、代わりに nanosleep()
を使用して、独自のsleep_us()
関数を作成し、設定されたマイクロ秒数だけスリープします。
_void sleep_us(unsigned long microseconds)
{
struct timespec ts;
ts.tv_sec = microseconds / 1e6; // whole seconds
ts.tv_nsec = (microseconds % 1e6) * 1e3; // remainder, in nanoseconds
nanosleep(&ts, NULL);
}
_
Linux Ubuntuでコンパイルおよび実行するために、sleep_test.cファイルを作成して使用しました:
_gcc -Wall -g3 -std=c11 -o sleep_test sleep_test.c && ./sleep_test
_
代わりにnanosleep()を使用するとうまくいきました。
関連する注意事項:usleep()はPOSIX-2008から削除され、代わりにnanosleep()を使用することを推奨しています。