I have a program that uses the <stdio.h> function dprintf. If I complie this without -std=c99 I have no problems, however if I try to compile wih this flag I'll get the "implicit function declaration" warning
Does this mean that dprintf is not declared in <stdio.h> for c99? If so, where is the function declaration?
dprintf is not in C99. It's only in recent versions of POSIX.
You can compile with -std=gnu99 to include both C99 and POSIX functions (plus some extensions).
dprintf is a Posix function, making it an extension to standard C.
Posix (and other) extension functions need to be enabled by defining an appropriate feature test macro before including any standard header. On Linux , at least, you'll find the appropriate feature test macro listed in the manpage, right after the prototype. For example, man dprintf tells you:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
dprintf(), vdprintf():
Since glibc 2.10:
_POSIX_C_SOURCE >= 200809L
Before glibc 2.10:
_GNU_SOURCE
That means that, assuming that you are using a not too ancient glibc version, your file should start:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
Although you can achieve the same effect on gcc by using non-standard -std options, using feature test macros correctly makes your code portable between different Posix implementations.
Related
I am doing an assignment which states: "The skeleton code given uses getopt. If you compile the code with -std=c99, there will be compilation
error. To fix the error, include -D_POSIX_C_SOURCE=200809 when you compile the code."
I am very new to this. Ordinarily I compile a C program with GCC (program name) and then I type ./a.out.
What am I required to do here?
The sentence “To fix the error, include -D_POSIX_C_SOURCE=200809 when you compile the code” means to include the characters -D_POSIX_C_SOURCE=200809 in the command you use to compile the program.
For example, if you normally use gcc -o foo foo.c, change it to gcc -o foo -D_POSIX_C_SOURCE=200809 foo.c.
This is a command line argument that tells the compiler to define a preprocessor macro named _POSIX_C_SOURCE to be replaced by 200809. This preprocessor macro is used by various header files to adapt to different versions of POSIX (by using #if statements to test the macro). For example, if you specify _POSIX_C_SOURCE to be 200809 or leave it undefined, the headers will not declare routines that were only added to POSIX after the 2008-09 version of POSIX. Among other things, this avoids causing conflicts with programs written before then that might have happened to use names of those routines for other purposes (since they would have had no way of knowing what names POSIX header would define in the future).
You can also define the macro in your source code, before any headers that use it are included, with:
#define _POSIX_C_SOURCE 200809
The getopt function is a relatively recent addition to the Single UNIX Specification/POSIX Standard. While Linux doesn't comply with POSIX, it does roughly use this standard as a reference point. However, it's mostly implementing XSH (System Headers) of POSIX '03 or earlier by default for compatibility. If you want more recent additions exposed (Note: #JonathanLeffler mentions that getopt is there for quite some time already, but Linux doesn't expose it by default anyway), you can tell the GNU libc (the C Library commonly used on GNU/Linux systems) to also provide some of that functionality which are hidden behind Feature Test Macros. Lookup the man-page man -s 7 feature_test_macros 2 in combination with man -s 3 getopt 1 for more. Basically, in the respective headers there's some code similar to the following:
#if _POSIX_C_SOURCE >= 200809L
/* declaration of getopt() and other newer functions */
#endif
If you then include that file and do not define the feature test macro to have a value greater than (newer/more recent than) the date of that POSIX standard you need (2008-09), the C Preprocessor will throw away all those forward declarations, making your code error out.
Using -DFOO=bar you #define FOO bar on the command line for the standard C Compiler. By the way, the GNU C Compiler also sets some of such flags when you use -std=c99.
In the end, your command line should look more or less like this:
$ c99 -D_POSIX_C_SOURCE=200809L -o foo foo.c
This will compile and link foo.c to the output file foo adhering to the C99 standard and using features from POSIX '08 3.
Using getchar_unlocked and compiling with --std=c99 flag gives warningas follows-
warning: implicit declaration of function ‘getchar_unlocked’ [-Wimplicit-function-declaration]
Does not give any warning if compiled without flag.Is there any way to work around with it ?
Starting from C99 you must have a visible function prototype before calling a function. While the earlier C standard would just stupidly assume that any function unknown to the compiler has the format int func (params), which in turn would cause severe bugs most of the time.
Properly declare a prototype for getchar_unlocked and the bug will go away.
Note that there is no such function present in any standard library. It seems you might have to include some non-standard library for the compiler to find the function.
_unlocked versions of get... functions are POSIX extensions. They are not part of the standard functions of C99. The full list of get... functions is given in 7.19.1.5: getwc, getwchar, getc, getchar, and gets (deprecated).
When the function is not on this list, C99-compliant compiler must warn you that your program may not compile with other C99-compliant compilers.
Dialect selection options like -ansi and -std=c99 cause the compiler to define certain macros (in addition to altering the accepted dialect).
Library header files react to those macros.
Precisely how they react is quite system-dependent (the compiler doesn't provide a C library), but a common behavior you can broadly expect is that if you use one of these flags alone (without any other "feature selection macro"), it has the effect of hiding the declarations of functions, macros and other global symbols which are not in the specified ISO C dialect.
ISO C knows nothing about getchar_unlocked. The presence of such a declaration in <stdio.h> (normally an ISO C header) is a POSIX extension, which is basically nonconforming, since getchar_unlocked is an identifier that strictly conforming C programs can use, even if they include <stdio.h>. When you use -ansi or -std=c99, the <stdio.h> header listens up and whips itself into ISO-C-conforming shape, hiding such extensions.
On well-behaved POSIX systems, you can request that you want an ISO C dialect and that you want certain rudimentary 1990-ish POSIX features to be visible in header files, for instance like this:
gcc -std=c99 -D_POSIX_SOURCE ...
^^^^^ "feature selection macro"
There is a whole science to these feature selection macros, too broad for this question and answer; some forms of them have values, like -D_XOPEN_SOURCE=500. _POSIX_SOURCE doesn't need an argument; it is just defined or not, but _POSIX_C_SOURCE is numeric.
I just checked glibc and Cygwin: on both, _POSIX_SOURCE is enough to reveal the getchar_unlocked declaration. It is quite old, dating back to POSIX.1 1996.
Beware: on some systems, multiple feature selection macros don't play along reasonably; they give you a set intersection rather than union, so that -D_POSIX_SOURCE and -D_BSD_SOURCE together end up meaning "Declare to me only those handful of functions that are specific to classic BSD that have been standardized in POSIX too", which means that next to nothing is declared.
getchar_unlocked is not a C standard function.
Compiling it forcing c99 standard does not support it natively.
I'm writing a program in C using Code::Blocks 13.12 on Windows 8 (the C compiler is mingw32-gcc). I would like to use the "getline" function but it seems to be missing from the stdio.h. Is there any way to get it except for writing own implementation?
getline is a POSIX function, and Windows isn't POSIX, so it doesn't have some POSIX C functions available.
You'll need to roll your own. Or use one that has already been written.
getline is not a standard C library function. Some implementations (such as gcc) provide it as an extension.
If you're compiling with gcc, you'll need to define the feature macro _GNU_SOURCE in order to make it available for your code:
#define _GNU_SOURCE
#include <stdio.h>
...
getline (...);
EDIT
Hopefully since mingw is a GNU compiler, this should be available for you on windows.
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 ...
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.