implizite Deklaration der Funktion usleep

Lesezeit: 8 Minuten

Benutzeravatar von ant2009
Ameise2009

gcc (GCC) 4.6.3
c89

Ich versuche zu verwenden usleep. Allerdings bekomme ich immer wieder folgende Warnung:

implizite Deklaration der Funktion usleep

Ich habe die eingeschlossen unistd.h Header-Datei.

Die Manpages erwähnen etwas darüber. Aber ich bin mir nicht sicher, ob ich es verstehe:

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

Aber nicht sicher, was ich mit dem oben genannten tun soll?

  • Der Vorschlag, den Sie verpasst haben, finden Sie auf derselben Manpage, auf der Sie den obigen Text kopiert haben: POSIX.1-2001 declares this function obsolete; use nanosleep(2) instead. POSIX.1-2008 removes the specification of usleep(). Sie sehen also, dass hinter der Tatsache, dass es so schwer zugänglich ist, eine Absicht steckt. Verwenden Sie es einfach nicht in neuem Code.

    – Jens Gustedt

    7. April 2012 um 15:50 Uhr

Benutzeravatar von paxdiablo
paxdiablo

Diese Liste ist die Voraussetzung dafür usleep definiert. Es ist im Grunde ein C-ähnlicher Ausdruck mit #define Variablen, die vor dem Einbinden der Header-Datei wahr sein müssen.

Die Header-Datei selbst wird nur definiert usleep in dem, was normalerweise ein riesiges Nest ist #ifdef Statements und die Entwickler haben sich die Zeit genommen, Ihnen zu sagen, was Sie tun müssen, damit Sie nicht stundenlang versuchen müssen, es selbst herauszufinden 🙂

Angenommen, Sie verwenden a glibc 2.12 oder besser, bedeutet dies, dass Sie entweder:

  • deklariere _BSD_SOURCE; oder
  • deklarieren eine komplizierte Kombination aus drei anderen Dingen, die ich nicht entschlüsseln werde.

Die wahrscheinlich einfachste Lösung ist, einfach mit zu kompilieren gcc -D _BSD_SOURCE oder setzen:

#define _BSD_SOURCE

in den Code, bevor Sie die Header-Datei einfügen, die Sie erhalten usleep.

Sie werden diese wahrscheinlich vorher definieren wollen irgendein beinhaltet, falls es Abhängigkeiten zwischen den verschiedenen Header-Dateien gibt.

  • Danke das hat funktioniert. Eigentlich musste ich _BSD_SOURCE vor allen anderen Includes deklarieren. Ansonsten gab es mir immer wieder die gleiche Warnung. Meine glibc-Version glibc-2.14.90-24.fc16.6.x86_64.

    – Ameise2009

    7. April 2012 um 11:24 Uhr

  • @ ant2009, ja, das ist wahrscheinlich, da es Abhängigkeiten zwischen Headern geben kann. Ich werde das der Antwort hinzufügen.

    – paxdiablo

    7. April 2012 um 11:25 Uhr

  • @paxdiablo meine Toolchain beschwert sich darüber warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"also nehme ich in manchen Fällen an _BSD_SOURCE behebt das Problem nicht

    – Piotr Król

    28. Januar 2016 um 13:01 Uhr

  • @PiotrKról Wenn Sie neuere Versionen von glibc> 2.19 verwenden, fügen Sie hinzu #define _DEFAULT_SOURCE. Wenn Ihr Code möglicherweise mit alten und neuen Versionen von glibc build erstellt wurde, definieren Sie _BSD_SOURCE auch. sourceware.org/glibc/wiki/Release/2.20#Packaging_Changes

    – knirschen117

    1. August 2017 um 19:29 Uhr


  • Der Weg, dies zu tun, der Standards bestätigt, ist das Setzen _XOPEN_SOURCE zu 600, was für Legacy-Code funktioniert. Für neuen Code, bei dem Sie neuere Schnittstellen im selben Programm verwenden müssen, können Sie ihn zur Verwendung neu schreiben nanosleep().

    – Davislor

    24. März 2020 um 17:37 Uhr


Benutzeravatar von ioilala
ioilala

Das könnte funktionieren: Hinzufügen -std=gnu99 beim Kompilieren mit gcc unter Linux.

Beispiel:

arm-linux-gcc -lpthread -std=gnu99  -o test ArmLinuxDataPipe1.2.1.c

  • Dies! Wenn Sie -std=c99 sagen, erhalten Sie eine Warnung.

    – Terroi

    4. April 2017 um 10:06 Uhr

Benutzeravatar von Davislor
Davislor

Tl; Dr

Wenn Sie Legacy-Code benötigen, der verwendet usleep() Fügen Sie zum Kompilieren diese Zeilen zu einer Header-Datei hinzu, die Sie vor allen anderen Bibliotheken einfügen:

#define _XOPEN_SOURCE   600
#define _POSIX_C_SOURCE 200112L

Oder fügen Sie die Compiler-Flags hinzu -std=c11 -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L zu deinem Makefile.

Das teilt der Umgebung mit, die Ihr Programm verwendet diese ältere Version der UNIX-APIin welchem usleep() wurde nicht verworfen.

Alternativ – und wenn es sich um neuen Code handelt, auf jeden Fall – ersetzen usleep() mit nanosleep()stellen Sie die Feature-Test-Makros entsprechend Ihrer Version der Bibliothek ein und überprüfen Sie Ihre Codebasis auf andere Bitfäule.

Unter Linux können Sie überprüfen, welche Werte von _XOPEN_SOURCE und _POSIX_C_SOURCE Ihre Bibliothek unterstützt in man feature_test_macros.

Das komplette Bild

Längere Antwort: Hier ist, was los ist.

Historisch gesehen gab es mehrere unterschiedliche UNIX-Standards, und die letztendliche Best Practice, auf die alle stießen, bestand darin, den Code anzugeben, für welche Version der UNIX-API er geschrieben wurde. Programmierer taten dies, indem sie ein Feature-Test-Makro definierten.

Eine der frühesten Trennungen in UNIX war die zwischen AT&Ts System V und der Berkeley Standard Distribution (BSD) der University of California. Da System V die offizielle Version war und sein Verhalten zum Standard wurde, während BSD Unix eine der frühesten freien Software war und an vielen Universitäten verwendet wurde, ist es viel häufiger, dass Legacy-Code deklariert wird _BSD_SOURCE als _SVID_SOURCE. Das _BSD_SOURCE macro versucht insbesondere über einen Zeitraum von mehr als vierzig Jahren, Erweiterungen von den unterschiedlichsten Betriebssystemen zu ermöglichen. Manchmal wird es sogar als Auffangbehälter für nicht standardmäßige Erweiterungen verwendet. Beide Makros sind veraltet, und im Gegensatz zur derzeit akzeptierten Antwort sollten Sie keines von beiden in neuem Code verwenden.

In diesem Jahrhundert gab es zwei UNIX-Standards, POSIX, das zum IEEE-Standard wurde, und die Single Unix Specification (SUS) der Open Group (X/Open). Der X/Open SUS ist eine Obermenge von POSIX und das, wofür Sie normalerweise schreiben würden. Früher gab es eine Reihe verschiedener Feature-Test-Makros, die Sie deklarieren konnten, um die damals aktuellen Versionen dieser Standards zu aktivieren, und diese werden aus Gründen der Abwärtskompatibilität immer noch unterstützt. Sie können einige davon in der eingefügten Bedingung sehen, aber Sie müssen sich keine Gedanken darüber machen, wenn Sie neuen Code schreiben. Ein Makro, das der Code überprüft, _XOPEN_SOURCE_EXTENDEDist jetzt veraltet, aber historisch gesehen eine Version des SUS von 1995.

Theoretisch ist das richtige Feature-Test-Makro für jede moderne Version von UNIX oder Linux geeignet _XOPEN_SOURCE. Sie sollten die neueste Versionsnummer nachschlagen, die Ihre Bibliothek unterstützt. In der Praxis halte ich es für klug, auch defensive Kodierungen zu definieren _POSIX_C_SOURCEum zu Garantie dass niemand sonst es inkonsistent setzen und Ihren Code brechen kann. Ihre Frage ist ein gutes Beispiel: Wenn Sie einstellen _XOPEN_SOURCE für Abwärtskompatibilität, aber _POSIX_C_SOURCE wird an anderer Stelle in Ihrer Toolchain auf eine neuere Version eingestellt, die höhere Version von _POSIX_C_SOURCE wird Vorrang haben und usleep() wird nicht funktionieren.

Also, was diese Bedingungen bedeuten, ist das usleep() war keine POSIX-Funktion, war aber zeitweise auf einigen BSD-ähnlichen Betriebssystemen vorhanden und schaffte es daher 1995 in den SUS. Sie wurde 2008 als veraltet markiert, und die Auswahl einer beliebigen Version von POSIX oder dem SUS seitdem deaktiviert sie aktiv. Daher ist es aktiviert, wenn Sie Version 500 oder 600 des SUS auswählen (und ein anderes veraltetes Synonym aktiviert es ebenfalls), aber veraltet, wenn Sie eine neuere Version von POSIX oder SUS auswählen. Sie werden auch aktiviert, wenn Sie die Option “Alles geht” auswählen, aber das ist eine schlechte Idee.

Benutzeravatar von Gabriel Staples
Gabriel Staples

Für noch bessere Sleep-Demos in C jetzt siehe my eRCaGuy_hello_world repo, in diesen Dateien zum Beispiel:

  1. sleep_nanosleep.c
  2. sleep_nanosleep_minimum_time_interval.c
  3. timinglib_sleep_and_sleep_until.c
  4. timinglib.h
  5. timinglib.c

nanosleep() Demo:

Fügen Sie Folgendes am Anfang Ihres Codes hinzu, mit dem #define _POSIX_C_SOURCE 199309L Teil kommt Vor #include <time.h>damit es die einbringt nanosleep() Funktion ab <time.h>!:

// This line **must** come **before** including <time.h> in order to bring in
// the POSIX functions such as `clock_gettime()`, `nanosleep()`, etc., from
// `<time.h>`!
#define _POSIX_C_SOURCE 199309L

// For `nanosleep()`:
#include <time.h>

Und dann verwenden nanosleep() stattdessen, um Ihre eigenen zu erstellen sleep_us() Funktion, um eine festgelegte Anzahl von Mikrosekunden zu schlafen:

void sleep_us(unsigned long microseconds)
{
    struct timespec ts;
    ts.tv_sec = microseconds / 1000000ul;            // whole seconds
    ts.tv_nsec = (microseconds % 1000000ul) * 1000;  // remainder, in nanoseconds
    nanosleep(&ts, NULL);
}

Zum Kompilieren und Ausführen unter Linux Ubuntu habe ich eine sleep_test.c Datei und verwendet:

gcc -Wall -g3 -std=c11 -o sleep_test sleep_test.c && ./sleep_test

Verweise:

  1. (Dies ist absichtlich ein Zirkelverweis: siehe meine Kommentare unter dieser Antwort): Gibt es eine alternative Schlaffunktion in C zu Millisekunden?
  2. http://man7.org/linux/man-pages/man2/nanosleep.2.html
    1. Erwähnungen:

    _POSIX_C_SOURCE >= 199309L

Verwandt:

  1. Eine andere Antwort von mir, die POSIX-Timing-Funktionen verwendet (z. B.: clock_gettime(): Holen Sie sich einen Zeitstempel in C in Mikrosekunden?

Weitergehen:

  1. Ausprobieren clock_nanosleep() mit einer monotonen Uhr und Flagge TIMER_ABSTIME stattdessen etwas Ähnliches zu erreichen FreeRTOS vTaskDelayUntil() Funktion, für präzise und wiederholbare periodische Aktionen.
    1. Erhöhen Sie die POSIX-Version mit #define _POSIX_C_SOURCE 200112L vor #include <time.h> um Zugang zu bekommen clock_nanosleep().

ANTWORT AUF DIE FRAGE: verwenden
#define _BSD_SOURCE oder #define _GNU_SOURCE

Für die mit dem Fehler

warning: #warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" [-Wcpp]
 # warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
   ^~~~~~~

nach der Verwendung #define _BSD_SOURCE versuchen Sie es mit

#define _GNU_SOURCE

HINWEIS: Verwenden Sie, bevor Sie die Kopfzeile einfügen, die Sie erhalten usleep() dh vor dem Einschließen unistd.h

Die Verwendung von nanosleep() funktionierte stattdessen für mich.

Zu einem relevanten Hinweis: usleep() wurde seit POSIX-2008 entfernt und empfiehlt stattdessen die Verwendung von nanosleep().

1387680cookie-checkimplizite Deklaration der Funktion usleep

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy