What does -D_DEFAULT_SOURCE do? - c

Previously I was receiving warnings from gcc -std=c99 that usleep() was implicitly declared. Then I stumbled across this stackoverflow post, which led me to use -D_BSD_SOURCE. However, now gcc tells me that -D_BSD_SOURCE has been deprecated and I should use -D_DEFAULT_SOURCE instead.
#warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
Why is -D_BSD_SOURCE deprecated? Why is -D_DEFAULT_SOURCE used instead? And what does it do?
I did some googling, and the results are just filled with people using it to shut gcc up. I couldn't find out why -D_BSD_SOURCE has been deprecated, just that it is.

The glibc manual describes each feature test macro (FTM) including _DEFAULT_SOURCE:
If you define this macro, most features are included apart from
X/Open, LFS and GNU extensions: the effect is to enable features from
the 2008 edition of POSIX, as well as certain BSD and SVID features
without a separate feature test macro to control them. Defining this
macro, on its own and without using compiler options such as -ansi or
-std=c99, has the same effect as not defining any feature test macros; defining it together with other feature test macros, or when options
such as -ansi are used, enables those features even when the other
options would otherwise cause them to be disabled.
This LWN.net article about FTMs provides us with a rationale (among other perhaps interesting info):
The original intent seems to have been that, within each of the glibc
header files that employs FTMs, only one of the __USE_* internal
macros should govern the exposure of any particular definition.
Additionally, the macros should not be used in nested #ifdef
directives. An inspection of the glibc header files quickly shows that
the reality is far from the intent, a situation that led Roland
McGrath to suggest that it was time for a major cleanup to bring
things back to the intended situation. Roland thought that task could
be simplified by eliminating the _BSD_SOURCE and _SVID_SOURCE FTMs,
which, although they had a purpose historically, have ceased to be
useful these days. Anymore, he said, the only macros that are needed
for modern source code are those that relate to formal standards plus
_GNU_SOURCE.
Joseph Myers duly obliged with a series of patches to implement the
first steps in this work. The conservative approach encouraged by
Roland meant that the deprecation of the _BSD_SOURCE and
_SVID_SOURCE FTMs is taking place across two glibc versions. Version
2.19 of glibc added a new FTM, _DEFAULT_SOURCE. Defining this macro causes the default definitions to be exposed even when the explicit
definition of other macros would cause that not to happen. The effect
of defining this macro is equivalent to the effect of explicitly
defining three macros in earlier glibc versions:
cc -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809C
So if you need to define _BSD_SOURCE or _SVID_SOURCE, simply define _DEFAULT_SOURCE too. glibc versions <= 2.18 don't care about it and versions >= 2.19 don't warn if both or all three are defined.

i need portability beyond linux and beyond glibc, and i dislike #ifdef's. so:
/* asprintf() does not appear on linux without this */
#define _GNU_SOURCE
/* gettimeofday() does not appear on linux without this. */
#define _BSD_SOURCE
/* modern glibc will complain about the above if it doesn't see this. */
#define _DEFAULT_SOURCE

Related

`__noinline__` macro conflict between GLib and CUDA

I'm working on an application using both GLib and CUDA in C. It seems that there's a conflict when importing both glib.h and cuda_runtime.h for a .cu file.
7 months ago GLib made a change to avoid a conflict with pixman's macro. They added __ before and after the token noinline in gmacros.h: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2059
That should have worked, given that gcc claims:
You may optionally specify attribute names with __ preceding and following the name. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use the attribute name __noreturn__ instead of noreturn.
However, CUDA does use __ in its macros, and __noinline__ is one of them. They acknowledge the possible conflict, and add some compiler checks to ensure it won't conflict in regular c files, but it seems that in .cu files it still applies:
#if defined(__CUDACC__) || defined(__CUDA_ARCH__) || defined(__CUDA_LIBDEVICE__)
/* gcc allows users to define attributes with underscores,
e.g., __attribute__((__noinline__)).
Consider a non-CUDA source file (e.g. .cpp) that has the
above attribute specification, and includes this header file. In that case,
defining __noinline__ as below would cause a gcc compilation error.
Hence, only define __noinline__ when the code is being processed
by a CUDA compiler component.
*/
#define __noinline__ \
__attribute__((noinline))
I'm pretty new to CUDA development, and this is clearly a possible issue that they and gcc are aware of, so am I just missing a compiler flag or something? Or is this a genuine conflict that GLib would be left to solve?
Environment: glib 2.70.2, cuda 10.2.89, gcc 9.4.0
Edit: I've raised a GLib issue here
It might not be GLib's fault, but given the difference of opinion in the answers so far, I'll leave it to the devs there to decide whether to raise it with NVidia or not.
I've used nemequ's workaround for now and it compiles without complaint.
GCC's documentation states:
You may optionally specify attribute names with __ preceding and following the name. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use the attribute name __noreturn__ instead of noreturn.
Now, that's only assuming you avoid double-underscored names the compiler and library use; and they may use such names. So, if you're using NVCC - NVIDIA could declare "we use noinline and you can't use it".
... and indeed, this is basically the case: The macro is protected as follows:
#if defined(__CUDACC__) || defined(__CUDA_ARCH__) || defined(__CUDA_LIBDEVICE__)
#define __noinline__ __attribute__((noinline))
#endif /* __CUDACC__ || __CUDA_ARCH__ || __CUDA_LIBDEVICE__ */
__CUDA_ARCH__ - only defined for device-side code, where NVCC is the compiler (ignoring clang CUDA support here).
__CUDA_LIBDEVICE__ - Don't know where this is used, but you're certainly not building it, so you don't care about that.
__CUDACC__ defined when NVCC is compiling the code.
So in regular host-side code, including this header will not conflict with Glib's definitions.
Bottom line: NVIDIA is (basically) doing the right thing here and it shouldn't be a real problem.
GLib is clearly in the right here. They check for __GNUC__ (which is what compilers use to indicate compatibility with GNU C, AKA the GNU extensions to C and C++) prior to using __noinline__ exactly as the GNU documentation indicates it should be used: __attribute__((__noinline__)).
GNU C is clearly doing the right thing here, too. Compilers offering the GNU extensions (including GCC, clang, and many many others) are, well, compilers, so they are allowed to use the double-underscore prefixed identifiers. In fact, that's the whole idea behind them; it's a way for compilers to provide extensions without having to worry about conflicts to user code (which is not allowed to declare double-underscore prefixed identifiers).
At first glance, NVidia seems to be doing the right thing, too, but they're not. Assuming you consider them to be the compiler (which I think is correct), they are allowed to define double-underscore prefixed macros such as __noinline__. However, the problem is that NVidia also defines __GNUC__ (quite intentionally since they want to advertise support for GNU extensions), then proceeds to define __noinline__ in an incompatible way, breaking an API provided by GNU C.
Bottom line: NVidia is in the wrong here.
As for what to do about it, well that's a less interesting question but there are a few options. You could (and should) file an issue with NVidia to fix their compiler. In my experience they're pretty good about responding quickly but unlikely to get around to fixing the problem in a reasonable amount of time.
You could also send a patch to GLib to work around the problem by doing something like
#if defined(__CUDACC__)
__attribute__((noinline))
#elif defined(__GNUC__)
__attribute__((__noinline__))
#else
...
#endif
If you're in control of the code which includes glib, another option would be to do something like
#undef __noinline__
#include glib_or_file_which_includes_glib
#define __noinline__ __attribute__((noinline))
My advice would be to do all three, but especially the first one (file an issue with NVidia) and find a way to work around it in your code until NVidia fixes the problem.

What does gcc -D_REENTRANT really do?

I am writing Java bindings for a C library, and therefore working with JNI. Oracle specifies, reasonably, that native libraries for use with Java should be compiled with multithread-aware compilers.
The JNI docs give the specific example that for gcc, this multithread-awareness requirement should be met by defining one of the macros _REENTRANT or _POSIX_C_SOURCE. That seems odd to me. _REENTRANT and _POSIX_C_SOURCE are feature-test macros. GCC and POSIX documentation describe their effects in terms of defining symbols and making declarations visible, just as I would expect for any feature-test macro.
If I do not need the additional symbols or functions, then do these macros in fact do anything useful for me? Does one or both cause gcc to generate different code than it otherwise would? Do they maybe cause my code's calls to standard library functions to be linked to different implementations? Or is Oracle just talking out of its nether regions?
Edit:
Additionally, it occurs to me that reentrancy is a separate consideration from threading. Non-reentrancy can be an issue even for single-threaded programs, so Oracle's suggestion that defining _REENTRANT makes gcc multithread-aware now seems even more dubious.
The Oracle recommendation was written for Solaris, not for Linux.
On Solaris, if you compiled a .so without _REENTRANT and ended up loaded by a multi-threaded application then very bad things could happen (e.g. random data corruption of libc internals). This was because without the define you ended up with unlocked variants of some routines by default.
This was the case when I first read this documentation, which was maybe 15 years ago, the mention of the -mt flag for the sun studio compiler was added after I last read this document in any detail.
This is no longer the case - You always get the same routine now whether or not you compile with the _REENTRANT flag; it's now only a feature macro, and not a behaviour macro.

c89 and POSIX at the same time

Is it possible to use POSIX functions even in strict std=c89? When I try to compile executable on Linux in strict ANSI C mode, both gcc and clang know nothing about functions like readlink or realpath, though headers are included. Since I have to use POSIX functions even in ANSI C mode, I'm looking for way to do it. I've thought about dlsym, but I don't know which library I'll have to open. Such calls are surrounded with #ifdef's, so they won't rise an alarm on the other system. Cross-platform solution needed. Thanks in advance!
You're looking for "feature-test macros". See the Single Unix Specification, Issue 6: System Interfaces Chapter 2.2, "The Compilation Environment"
Edit:
To quote that page:
The _POSIX_C_SOURCE Feature Test Macro
A POSIX-conforming application should ensure that the feature test macro
_POSIX_C_SOURCE is defined before inclusion of any header.
GCC and clang currently define _POSIX_C_SOURCE for you by default unless one of c89, c99, c11, or any behaviorally equivalent string is passed to the compiler's -std option.
Additionally:
The _XOPEN_SOURCE Feature Test Macro
An XSI-conforming application should ensure that the feature test macro
_XOPEN_SOURCE is defined with the value 600 before inclusion of any header.
This is needed to enable the functionality described in The _POSIX_C_SOURCE
Feature Test Macro and in addition to enable the XSI extension.
In other words, to guarantee your program (a.k.a. application) can use POSIX, either #define _POSIX_C_SOURCE 200112L before any header is included or pass the -D_POSIX_C_SOURCE=200112L option to the compiler. For the XSI functionality, you must define _XOPEN_SOURCE to a value of 600.
There is also a newer version of the Single Unix Specification — Issue 7. Very similar text can be found in Issue 7. The only real differences with respect to the text above are the numbers for _POSIX_C_SOURCE and _XOPEN_SOURCE have been changed.
At least when a combination of gcc and glibc on linux, you can turn on non standard functions (e.g. those defined by posix) with #define's , see man feature_test_macros
e.g. #define _POSIX_C_SOURCE 200809L before including any header files, or by adding it to the compiler arguments:
gcc -std=c99 -D_POSIX_C_SOURCE=200809L ...

implicit declaration of function usleep

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?
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:
declare _BSD_SOURCE; or
declare a complicated combination of three other things, which I won't bother to decode.
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.
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
Tl;dr
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.
The Complete Picture
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.
For even better sleep demos in C now, see my eRCaGuy_hello_world repo, in these files, for example:
sleep_nanosleep.c
sleep_nanosleep_minimum_time_interval.c
timinglib_sleep_and_sleep_until.c
timinglib.h
timinglib.c
nanosleep() demo:
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
References:
(This is intentionally a circular reference: see my comments under this answer): Is there an alternative sleep function in C to milliseconds?
http://man7.org/linux/man-pages/man2/nanosleep.2.html
Mentions:
_POSIX_C_SOURCE >= 199309L
Related:
Another answer of mine which uses POSIX timing functions (ex: clock_gettime(): Get a timestamp in C in microseconds?
Going further:
Try out 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.
Increase the POSIX version by using #define _POSIX_C_SOURCE 200112L prior to #include <time.h> in order to get access to clock_nanosleep().
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
Using nanosleep() instead worked for me.
On a relevant note: usleep() has been removed since POSIX-2008 and
recommends to use nanosleep() instead.

sigaction System Call

I was looking at the man page of sigaction, and I ended up looking at the following line.
sigaction(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
What do _POSIX_X_SOURCE, _X_OPEN_SOURCE, _POSIX_SOURCE mean? What to do with it?
These are feature test macros. Their purpose is to allow your program to inform the system header files which standards you want it to attempt to conform to, and what extensions you want available.
Without any feature test macros defined, implementations vary a lot in what macros, functions, and type definitions they make visible in their headers. A common practice is to make everything visible by default, which is a problem because "everything" is not very specific, and it's very possible that symbol names used in your program might clash with some of the extensions. Even if they don't clash now, there's no way to know if they will in the future. So the standards (like ISO C and POSIX) put strict requirements on the implementation that it not pollute the applications namespace with names not explicitly defined or reserved in the standards. When you use a feature test macro to request a particular standard, you're asking the implementation to ensure that (1) it provides everything defined in this standard, (2) it doesn't pollute your application's namespace by providing anything not defined in that standard.
A correct program should always explicitly use the right feature test macros for the standard(s) it's written to. The easiest way to do this is putting the right -D argument on the compiler command line (CFLAGS). Adding the #define as the first line in each source file also works. Be aware if you do it in source files though:
The feature test macros must be defined at the top before any system header is included.
It's usually a bad idea to use different feature test macros in different translation units.
As an aside, it's not exactly the same as the other feature test macros, but all modern programs should define _FILE_OFFSET_BITS=64 when built on Linux/glibc to request that off_t be 64-bit for large file support.
Here is a man for Feature macros: http://www.kernel.org/doc/man-pages/online/pages/man7/feature_test_macros.7.html
They will turn on or off some level of standard support in the headers.
E.g. _POSIX_C_SOURCE >= 1 means that POSIX.2-1992 or later should be supported; _X_OPEN_SOURCE means POSIX.1, POSIX.2, and XPG4 are enabled; and for greater values of macro (>=500; >=600; >=700) it will also turn on some variants of SUSv2 v3 or v4 (UNIX 98; 03 or POSIX.1-2008+XSI). And _POSIX_SOURCE is an obsolete way to define _POSIX_C_SOURCE = 1
They're the things you have to #define to get the prototype, and are known as feature test macros.
For example, the following code will susscessfully define the prototype for sigaction:
#define _XOPEN_SOURCE
#include <signal.h>
Including signal.h without that #define (or the others) will not define the prototype.
It is a Feature test macro.
Symbols called "feature test macros" are used to control the visibility of symbols that might be included in a header. Implementations, future versions of IEEE Std 1003.1-2001, and other standards may define additional feature test macros.

Resources