Reputation: 22526
gcc (GCC) 4.6.3
c89
I am trying to use usleep
. However, I keep getting the following warning:
implicit declaration of function usleep
I have included the unistd.h
header file.
The man pages mentions something about this. But I am not sure I understand by it:
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
But not sure what I a to do with the above?
Upvotes: 38
Views: 79036
Reputation: 52787
For even better sleep demos in C now, see my eRCaGuy_hello_world repo, in these files, for example:
nanosleep()
demo: how to write your own sleep_us()
function from nanosleep()
Add the following to the top of your code, with the #define _POSIX_C_SOURCE 199309L
part coming before #include <time.h>
, so that it will bring in the nanosleep()
function from <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>
And then use nanosleep()
instead, to create your own sleep_us()
function to sleep a set number of microseconds:
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);
}
For compiling and running on Linux Ubuntu, I created a sleep_test.c file and used:
gcc -Wall -g3 -std=c11 -o sleep_test sleep_test.c && ./sleep_test
_POSIX_C_SOURCE >= 199309L
clock_gettime()
: Get a timestamp in C in microseconds?clock_nanosleep()
with a monotonic clock and flag TIMER_ABSTIME
instead, to achieve something similar to FreeRTOS's vTaskDelayUntil()
function, for precise and repeatable periodic actions.
#define _POSIX_C_SOURCE 200112L
prior to #include <time.h>
in order to get access to clock_nanosleep()
.Upvotes: 8
Reputation: 544
ANSWER TO QUESTION:
use
#define _BSD_SOURCE
or #define _GNU_SOURCE
For those with the error
warning: #warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" [-Wcpp]
# warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
^~~~~~~
after using #define _BSD_SOURCE
try using
#define _GNU_SOURCE
NOTE: use before you include the header that gives you usleep()
i.e. before including unistd.h
Upvotes: 4
Reputation: 15144
If you need to get legacy code that uses usleep()
to compile, add these lines to a header file that you include before any other libraries:
#define _XOPEN_SOURCE 600
#define _POSIX_C_SOURCE 200112L
Or add the compiler flags -std=c11 -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L
to your makefile.
That tells the environment that your program uses this older version of the UNIX API, in which usleep()
was not deprecated.
Alternatively—and if this is new code, definitely—replace usleep()
with nanosleep()
, set the feature-test macros appropriately for your version of the library, and review your codebase for other bit rot.
On Linux, you can check which values of _XOPEN_SOURCE
and _POSIX_C_SOURCE
your library supports in man feature_test_macros
.
Longer answer: Here’s what’s going on.
There historically were several different UNIX standards, and the eventual best practice everyone hit on was to have the code specify what version of the UNIX API it was written for. Programmers did this by defining a feature-test macro.
One of the earliest splits in UNIX was between AT&T’s System V and the Berkeley Standard Distribution (BSD) from the University of California. Since System V was the official version and its behavior became the default, whereas BSD Unix was some of the earliest free software and used in many universities, it’s much more common to see legacy code declare _BSD_SOURCE
than _SVID_SOURCE
. The _BSD_SOURCE
macro especially tries to enable extensions from a wide variety of different operating systems over a period of more than forty years. Sometimes, it’s even used as a catch-all for non-standard extensions. Both macros are deprecated, and contrary to the currently-accepted answer, you should never use either one in new code.
In this century, there were two UNIX standards, POSIX, which became an IEEE standard, and the Single Unix Specification (SUS) from the Open Group (X/Open). The X/Open SUS is a superset of POSIX and what you would normally write for. There used to be a number of different feature-test macros that you could declare to enable then-current versions of these standards, and these are still supported for backward compatibility. You can see some of them in the conditional you pasted, but you don’t need to worry about them when you write new code. One macro that code checks, _XOPEN_SOURCE_EXTENDED
, is now obsolete, but historically selected a version of the SUS from 1995.
In theory, the correct feature-test macro to set on any modern version of UNIX or Linux is _XOPEN_SOURCE
. You should look up the most recent version number that your library supports. In practice, I think it’s prudent defensive coding to also define _POSIX_C_SOURCE
, in order to guarantee that nobody else can set it inconsistently and break your code. Your question is a good example: if you set _XOPEN_SOURCE
for backward-compatibility, but _POSIX_C_SOURCE
gets set to a more recent version elsewhere in your toolchain, the higher version of _POSIX_C_SOURCE
will take precedence and usleep()
will not work.
So, what those conditionals mean is that usleep()
was not a POSIX function, but was at one time present on some BSD-like OSes, and therefore made it into the SUS in 1995. It was deprecated in 2008, and selecting any version of POSIX or the SUS since then actively disables it. Therefore, it’s enabled if you select version 500 or 600 of the SUS (and one other obsolete synonym also turns it on), but deprecated if you select any recent version of POSIX or the SUS. They’re also enabled if you select the anything-goes option, but that’s a bad idea.
Upvotes: 8
Reputation: 57
Using nanosleep() instead worked for me.
On a relevant note: usleep() has been removed since POSIX-2008 and recommends to use nanosleep() instead.
Upvotes: 1
Reputation: 881643
That list is the pre-conditions for having usleep
defined. It's basically a C-like expression involving #define
variables which has to be true before including the header file.
The header file itself will only define usleep
inside what is usually a massive nest of #ifdef
statements and the developers have taken the time to tell you what you need to do so that you don't have to spend hours trying to figure it out yourself :-)
Assuming you're using a glibc
2.12 or better, it means you either have to:
Probably the easiest fix is to simply compile with gcc -D _BSD_SOURCE
or put:
#define _BSD_SOURCE
in the code before you include the header file that gives you usleep
.
You'll probably want to define these before any includes in case there are dependencies between the various header files.
Upvotes: 41
Reputation: 297
This may work: Add -std=gnu99
when compiling with gcc on Linux.
Example:
arm-linux-gcc -lpthread -std=gnu99 -o test ArmLinuxDataPipe1.2.1.c
Upvotes: 24