I'm using GCC 4.6.0 (on an otherwise unidentified platform).
I am using the crypt() function to encrypt a password.
I have never used that function before so I checked out the main page:
man 3 crypt
And it says to include the unistd.h header.
However, when I did that, I got an implicit warning for the crypt function.
warning: implicit declaration of function ‘crypt’ [-Wimplicit-function-declaration]
I did a bit of searching and I found that you have to include the crypt.h. However, how come it doesn't say that in the man page?
It also says #define _XOPEN_SOURCE (before including unistd.h) in my man page. So you should probably add it to expose the declaration of crypt.
EDIT
I just tried it. Including unistd.h and #define _XOPEN_SOURCE before it does the trick. Including it alone isn't enough.
Using
gcc version 4.6.0 20110429
GNU C Library stable release version 2.13
Looking into unistd.h:
/* XPG4.2 specifies that prototypes for the encryption functions must
be defined here. */
#ifdef __USE_XOPEN
/* Encrypt at most 8 characters from KEY using salt to perturb DES. */
extern char *crypt (__const char *__key, __const char *__salt)
__THROW __nonnull ((1, 2));
The POSIX standard for crypt() says that it should be declared in <unistd.h>, so that's what you need to include.
However, depending on what other compiler options you specify, you may or may not see it.
I currently use a header I call "posixver.h" which contains the code:
#ifndef JLSS_ID_POSIXVER_H
#define JLSS_ID_POSIXVER_H
/*
** Include this file before including system headers. By default, with
** C99 support from the compiler, it requests POSIX 2001 support. With
** C89 support only, it requests POSIX 1997 support. Override the
** default behaviour by setting either _XOPEN_SOURCE or _POSIX_C_SOURCE.
*/
/* _XOPEN_SOURCE 700 is loosely equivalent to _POSIX_C_SOURCE 200809L */
/* _XOPEN_SOURCE 600 is loosely equivalent to _POSIX_C_SOURCE 200112L */
/* _XOPEN_SOURCE 500 is loosely equivalent to _POSIX_C_SOURCE 199506L */
#if !defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE)
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600 /* SUS v3, POSIX 1003.1 2004 (POSIX 2001 + Corrigenda) */
#else
#define _XOPEN_SOURCE 500 /* SUS v2, POSIX 1003.1 1997 */
#endif /* __STDC_VERSION__ */
#endif /* !_XOPEN_SOURCE && !_POSIX_C_SOURCE */
#endif /* JLSS_ID_POSIXVER_H */
On the systems where I work, setting _XOPEN_SOURCE to 700 would be an exercise in frustration and futility, however much I'd like to be able to do so. But these options normally make my code work correctly on Linux, HP-UX, MacOS X, AIX and Solaris - the Unix-like platforms I normally work on.
And this works when I set GCC into -std=c99 mode. If you use -std=gnu99, you probably don't need the header at all; it automatically enables C99 standard plus extensions.
Incidentally, I used to have this stanza at the top of individual source files. As the number of files containing the stanza grew (encroaching on hundreds of files), I realized that when I needed to adjust the settings, I had a monstrous editing job ahead of me. Now I have the one header and I'm retrofitting it into the files that have the stanza so I change one file (the header) to effect a change for all my code - once I've finished undoing the damage I did.
Related
I would like to open a file and set its size so that I can then use mmap to write to it.
I found that I can use function truncate or ftruncate. Unfortunately, when I include <unistd.h> I got error:
error: implicit declaration of function ‘truncate’
I read on Internet that I should use gnu or something like that but this is for school project and we have to compile with -std=c99.
Are there any alternatives?
When you use -std=c99 the C library makes sure that the headers do not declare any symbols that are not reserved/are not defined in the C standard library. Since ftruncate does not belong to the C standard library, being a POSIX extension instead, it is not defined by default.
A POSIX program must, for maximal compatibility, define the _POSIX_C_SOURCE feature test macro, or _XOPEN_SOURCE, with appropriate values, before including the headers.
The feature test macros are listed conveniently on for example Linux manual pages; for ftruncate these would be:
ftruncate():
_XOPEN_SOURCE >= 500
|| /* Since glibc 2.3.5: */ _POSIX_C_SOURCE >= 200112L
|| /* Glibc versions <= 2.19: */ _BSD_SOURCE
i.e. use
#define _XOPEN_SOURCE 500 // (or greater; current is 700)
#include <unistd.h>
or
#define _POSIX_C_SOURCE 200112L // (or greater)
#include <unistd.h>
I get the following error when I run my code:
error: implicit declaration of function ‘mkdtemp’ [-Werror=implicit-function-declaration]
This occurs even after including the correct header files for mkdtemp():
#include <stdlib.h>
Any ideas why this might be occurring?
The <stdlib.h> header is mandated by the C standard. The C standard makes no reference to a mkdtemp() function. If you're using gcc -std=c11 or some similar option, only the definitions provided by the C standard are exposed. If you compile using gcc -std=gnu11, then you'll get an indeterminate set of extension features enabled (and mkdtemp() would be one of them).
Since mkdtemp() is a POSIX function, you can explicitly request it by defining the appropriate enabling macro before including any standard header. A command-line option -D_XOPEN_SOURCE=700 would (probably) do the job, for example; there's also the option of using -D_POSIX_C_SOURCE=200809 but remembering the correct number is harder (it is the date of the POSIX 2008 standard as year and month).
Or you can place the appropriate #define at the top of the file:
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700
#endif
or:
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif
These stanzas allow you to override the POSIX version on the command line. Simply writing the #define without the conditional around it would generate a warning (or error) for a non-benign redefinition of the macro.
There used to be major differences between the POSIX and X/Open functionality — X/Open included some things that POSIX doesn't. This distinction is smaller these days, and generally, you'll not get into trouble using the X/Open macro.
There are other enabling macros for other platforms, but one of these two will enable the declaration of mkdtemp(). On Linux (RHEL 7.x), /usr/include/features.h) documents these enabling macros:
/* These are defined by the user (or the compiler)
to specify the desired environment:
__STRICT_ANSI__ ISO Standard C.
_ISOC99_SOURCE Extensions to ISO C89 from ISO C99.
_ISOC11_SOURCE Extensions to ISO C99 from ISO C11.
_POSIX_SOURCE IEEE Std 1003.1.
_POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if >=2 add IEEE Std 1003.2;
if >=199309L, add IEEE Std 1003.1b-1993;
if >=199506L, add IEEE Std 1003.1c-1995;
if >=200112L, all of IEEE 1003.1-2004
if >=200809L, all of IEEE 1003.1-2008
_XOPEN_SOURCE Includes POSIX and XPG things. Set to 500 if
Single Unix conformance is wanted, to 600 for the
sixth revision, to 700 for the seventh revision.
_XOPEN_SOURCE_EXTENDED XPG things and X/Open Unix extensions.
_LARGEFILE_SOURCE Some more functions for correct standard I/O.
_LARGEFILE64_SOURCE Additional functionality from LFS for large files.
_FILE_OFFSET_BITS=N Select default filesystem interface.
_BSD_SOURCE ISO C, POSIX, and 4.3BSD things.
_SVID_SOURCE ISO C, POSIX, and SVID things.
_ATFILE_SOURCE Additional *at interfaces.
_GNU_SOURCE All of the above, plus GNU extensions.
_REENTRANT Select additionally reentrant object.
_THREAD_SAFE Same as _REENTRANT, often used by other systems.
_FORTIFY_SOURCE If set to numeric value > 0 additional security
measures are defined, according to level.
Note, too, that the manual page for mkdtemp() shows what is needed:
NAME
mkdtemp - create a unique temporary directory
SYNOPSIS
#include <stdlib.h>
char *mkdtemp(char *template);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
mkdtemp():
_BSD_SOURCE
|| /* Since glibc 2.10: */
(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
What I called 'enabling macros' are also known as 'Feature Test' macros.
See also POSIX System Interfaces: General Information: The Compilation Environment.
Have a time date string I'd like to convert to a tm object. Google tells me the POSIX (but not the C) standard includes a function called strptime() that will do the job.
The man page says it's in <time.h> and that I need to include #define _XOPEN_SOURCE before I include the <time.h> file. Easy enough.
But I still get an implicit declaration warning from the compiler. I opened /usr/include/time.h and found the function declaration:
# ifdef __USE_XOPEN
/* Parse S according to FORMAT and store binary time information in TP.
The return value is a pointer to the first unparsed character in S. */
extern char *strptime (const char *__restrict __s,
const char *__restrict __fmt, struct tm *__tp)
__THROW;
#endif
So it looks like I need #define _USE_XOPEN instead.
Except that doesn't work either. The compiler still isn't seeing the declaration.
Any ideas. I'm using a relatively recent version of Linux (Mint) with gcc 5.4.0.
Converting comments into an answer.
To fix this, your options include using -std=gnu11 instead of -std=c11 on the GCC command line, or using #define _XOPEN_SOURCE 700 or equivalent (e.g. -D_XOPEN_SOURCE=700 on the command line). The 700 identifies POSIX 2008; 600 or 500 identify earlier versions of POSIX or X/Open.
In theory, you could also use _POSIX_C_SOURCE 200809L (see POSIX Compilation environment), but that doesn't expose everything that _XOPEN_SOURCE 700 exposes so it is usually better to use the latter.
Note that the POSIX specification of strptime() is annotated as an XSI extension, which means you must set _XOPEN_SOURCE; setting _POSIX_C_SOURCE alone is not sufficient.
Test code
This test code prints the address of the strptime function; it won't compile if strptime() is not declared.
#define _XOPEN_SOURCE 700
#include <time.h>
#include <stdio.h>
int main(void)
{
printf("%p\n", (void *)strptime);
return 0;
}
That should compile for you with gcc -std=c11 -Wall -c test-strptime.c. If you add -ansi to the options, you reset the standard back to C90. GCC 5.4.0 should default to C11 (effectively -std=gnu11) unless someone did something horrible in the build of GCC that you're using (which is unlikely).
Note that the compiler unsets and then sets __USE_XOPEN based on settings like _XOPEN_SOURCE and trying to set it manually doesn't work reliably.
Position matters
You must specify the #define _XOPEN_SOURCE 700 before the first system header is included (whether included directly or indirectly). If you include a system header before trying to set _XOPEN_SOURCE, the settings have been determined and your subsequent operations are effectively ignored. POSIX says (at the 'compilation environment' link already given):
In the compilation of an application that #defines a feature test macro specified by POSIX.1-2008, no header defined by POSIX.1-2008 shall be included prior to the definition of the feature test macro. This restriction also applies to any implementation-provided header in which these feature test macros are used. If the definition of the macro does not precede the #include, the result is undefined.
One common undefined result is that your attempt to set/change the POSIX version is completely ignored.
I have seen strdup used in code samples on StackOverflow and have just tried to use it on Linux (3.0.0-21-generic x86_64).
The compiler (clang) knew it was in string.h, but still complained about not having a prototype even with string.h included. It turns out that strdup is wrapped in a #if defined, in string.h. I searched this site and found a post that said that strdup is a POSIX routine, not a C standard library routine.
The possible macros that will expose it are
__USE_SVID
__USE_BSD
__USE_XOPEN_EXTENDED
__USE_XOPEN2K8
Each one of those is undefined in features.h which is included by stdlib.h.
Why isn't a POSIX macro in that list and which macro/compiler switch are people using to expose strdup in string.h?
Edit: per Jim's comment below I found that
#define _POSIX_SOURCE 1
or
#define _POSIX_C_SOURCE 1
above
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
do not expose strdup on my system.
But these do:
#define _BSD_SOURCE 1
#define _SVID_SOURCE 1
Edit 2: Per Keith's comment, I found that this also works:
#define _POSIX_C_SOURCE 200809L
Edit 3: Per Jonathan's comment these also work
#define _XOPEN_SOURCE 500
#define _XOPEN_SOURCE 600
#define _XOPEN_SOURCE 700
The __USE... macros are for internal use. You should define _POSIX_SOURCE, or possibly one of the other feature macros as described in the comments in your feature.h ... for example, from a version I just grabbed off the web (apparently an old and somewhat obsolete version),
__STRICT_ANSI__ ANSI Standard C.
_POSIX_SOURCE IEEE Std 1003.1.
_POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if ==2 add IEEE Std 1003.2.
_BSD_SOURCE ANSI, POSIX, and 4.3BSD things.
_SVID_SOURCE ANSI, POSIX, and SVID things.
_GNU_SOURCE All of the above, plus GNU extensions.
So defining _GNU_SOURCE would get you everything.
Edit: from the comment by Keith Thompson, you need
#define _POSIX_C_SOURCE 200809L
for strdup.
What is the purpose of this macro: ISO_C_VISIBLE? I found it in the assert.h file.
Is it used to know which C version we are using?
Here's what an OpenBSD cdefs.h has to say about __ISO_C_VISIBLE and some related macros:
/*
* "The nice thing about standards is that there are so many to choose from."
* There are a number of "feature test macros" specified by (different)
* standards that determine which interfaces and types the header files
* should expose.
*
* Because of inconsistencies in these macros, we define our own
* set in the private name space that end in _VISIBLE. These are
* always defined and so headers can test their values easily.
* Things can get tricky when multiple feature macros are defined.
* We try to take the union of all the features requested.
*
* The following macros are guaranteed to have a value after cdefs.h
* has been included:
* __POSIX_VISIBLE
* __XPG_VISIBLE
* __ISO_C_VISIBLE
* __BSD_VISIBLE
*/
That particular cdefs.h sets __ISO_C_VISIBLE accrording to whatever POSIX specification level is configured.
So these are macros that BSD uses to attempt to 'condense' the other various feature macros used in the Unix world to configure a build environment into a more manageable set that other headers can rely on.
For example, setting the __ISO_C_VISIBLE macro appropriately (which the user will do indirectly by setting other documented feature macros) will allow older programs that might have names that conflict with C99 names continue to compile cleanly - if the build is properly configured, those conflicting C99 names will not be 'activated', the the use of those names in the user's program will not conflict.
If you look in the assert.h file for that OpenBSD source drop, you'll see:
# if __ISO_C_VISIBLE >= 1999
# define assert(e) ((e) ? (void)0 : __assert2(__FILE__, __LINE__, __func__, #e))
# else
# define assert(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__, #e))
# endif
So, if the build is configured to use C99 features the assert macro will take advantage of C99's __func__ feature so an assertion will indicate which function the assertion was in. If the build is configured to indicate that C99 features should not be used, assert() won't do that.
Note that these macros are not a general standard - they seem to be mostly in the BSD world, but I'm sure you'll find other areas where they might be used (probably because files got borrowed from BSD).
A Google search for "ISO_C_VISIBLE" turns up this question and a handful of results for Nokia's Symbian operating system. The only description says:
__ISO_C_VISIBLE 1999
Description
Macro value to enable for ISO_C_VISIBLE
My guess is that the value 1999 refers to the 1999 ISO C standard, but I see no further explanation of what it means or how it's used, or of the distinction between __ISO_C_VISIBLE and ISO_C_VISIBLE. It seems odd because Symbian is primarily implemented and programmed in C++, not C. And I certainly wouldn't expect it to be defined in <assert.h> (assuming that when you say assert.h you're referring to the header that's included by #include <assert.h>).
If you're not working with Symbian, then I have no idea what it might be.
The proper way to determine which C standard your implementation conforms to is to use the predefined STDC and STDC_VERSION macros. For a conforming C90 or later implementation, __STDC__ expands to 1. For a C99 implementation, __STDC_VERSION__ expands to 199901L. For C11, it probably expands to 201112L, but I haven't seen an actual copy of the new standard.
These macros are used for configuring for the system compiling the code. Information gathered from the compiler is stored in them so the code is [shaped] according to the constructs supported by the hosting platform.
/* ... */
#ifdef _POSIX_C_SOURCE
#if _POSIX_C_SOURCE >= 200112
#define __POSIX_VISIBLE 200112
#define __ISO_C_VISIBLE 1999
#elif _POSIX_C_SOURCE >= 199506
#define __POSIX_VISIBLE 199506
/* ... */