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.
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>
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 am using GCC 4.9 on ubuntu 15.04. I am coding in eclipse CDT. This is a C program with the dialect set to c99. For some reason my compiler keeps warning me about this...
warning: implicit declaration of function ‘posix_memalign’ [-Wimplicit-function-declaration]
I am not sure why. I have #include<stdlib.h> at the top and when I use eclipse the ctrl+click posix_memalign it takes me to the function declaration in stdlib.h. Why am I getting this warning?
I just tried changing the dialext to std=gnu99 and this fixed the issue. Is posix_memalign not included with c99?
The #define _POSIX_C_SOURCE 200809L and other feature test macros have to be defined before any #include lines.
This is because the macros tell the standard C library headers which features it should provide in addition/instead of the standard C library features; the features are "locked" at the point of #include.
posix_memalign() is provided by stdlib.h, but only if POSIX.1-2001 or later are enabled; this means defining _POSIX_C_SOURCE as 200112L or larger (the L is there because it is an integer constant of long type), or _XOPEN_SOURCE with 600 or larger.
The error shown only occurs when
The macros were not defined when stdlib.h was included
or
stdlib.h was not included
or
The C library implementation does not provide POSIX.1 features
Using GCC in Ubuntu, it has to be one of the first two, because the C library most definitely does provide these POSIX.1 features.
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
/* ... */
Is an ANSI C-compliant implementation allowed to include additional types and functions in its standard library, beyond those enumerated by the standard? (An ideal answer would reference the relevant part of the ANSI standard.)
I ask particularly because Mac OS 10.7 declares the getline function in stdio.h, even when compiling with gcc or clang using the -ansi flag. This breaks several older programs that define their own getline function. Is this a fault of Mac OS 10.7? (The man page for getline on Mac OS 10.7 says that getline conforms to the POSIX.1 standard, which came in 2008.)
Edit: To clarify, I find it odd that including stdio.h in an ANSI C89 program on Mac OS 10.7 also pulls in the declaration for the getline function, since getline is not one of the functions enumerated in the K&R (and presumably ANSI) description of stdio.h. In particular, attempting to compile noweb:
gcc -ansi -pedantic -c -o notangle.o notangle.c
In file included from notangle.nw:28:
getline.h:4: error: conflicting types for ‘getline’
/usr/include/stdio.h:449: error: previous declaration of ‘getline’ was here
Is it a bug in Mac OS 10.7 includes the declaration of getline in stdio.h even when compiling for the ANSI C89 standard?
From section 7.1.3 paragraph 2 of n1570 (which is a draft of C1x):
No other identifiers are reserved.
This is the part that means getline shouldn't be defined by the <stdio.h>, since it's not a reserved identifier according to the spec. So if your library defines getline in <stdio.h>, it's not technically compliant with the C standard...
However, you should be able to use the feature test macros to cause getline to be undefined in <stdio.h>.
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
This will give you only the definitions from the older POSIX standards. This won't work on some GNU C++ implementations, which is ExTrEmeLY fruSTRaTiNG for some folks.
The relevant section of the manpage is (taken from a glibc manpage, sorry...)
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
getline(), getdelim():
Since glibc 2.10:
_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
Before glibc 2.10:
_GNU_SOURCE
This part of the manpage tells you which macros need to be defined to which values in order to get the definition. My bet is that _POSIX_C_SOURCE is already defined by your compiler to 200809L.
The idea of feature test macros is that if you define your macros, like _POSIX_C_SOURCE, _BSD_SOURCE, _XOPEN_SOURCE, etc. to the values you want, you won't need to worry about new library functions clashing with your existing functions. There is also _GNU_SOURCE, which turns everything on if you use glibc, but I suggest giving that macro a wide berth.
Yes, a compliant implementation is allowed to define additional identifiers, including functions, as long as they are one of the reserved identifiers in the standard. For example:
All identifiers that begin with an underscore and either an uppercase letter or another
underscore are always reserved for any use;
All identifiers that begin with an underscore are always reserved for use as identifiers
with file scope in both the ordinary and tag name spaces;
All external names that begin with is, to, str, mem or wcs followed by a lowercase letter;
In addition there are names that are reserved only if you include certain headers; for example, if you include <errno.h> then it can define any macro starting with E followed by a digit or uppercase letter.
However, getline() is not such a reserved name, and a compliant implementation must make it available for the programmer's own use.