implicit declaration of function ‘gmtime_r’ - c

What do I need to do to make gcc include the declaration of gmtime_r(3) from time.h? Looking at /usr/include/time.h, gmtime_r and localtime_r are inside #ifdef __USE_POSIX.
Do I need to do something to turn __USE_POSIX on, like a command-line option? I'm running with -std=c99 now. I understand that __USE_* macros are not intended to be set directly by user code.
/* Return the `struct tm' representation of *TIMER
in Universal Coordinated Time (aka Greenwich Mean Time). */
extern struct tm *gmtime (const time_t *__timer) __THROW;
/* Return the `struct tm' representation
of *TIMER in the local timezone. */
extern struct tm *localtime (const time_t *__timer) __THROW;
#ifdef __USE_POSIX
/* Return the `struct tm' representation of *TIMER in UTC,
using *TP to store the result. */
extern struct tm *gmtime_r (const time_t *__restrict __timer,
struct tm *__restrict __tp) __THROW;
/* Return the `struct tm' representation of *TIMER in local time,
using *TP to store the result. */
extern struct tm *localtime_r (const time_t *__restrict __timer,
struct tm *__restrict __tp) __THROW;
#endif /* POSIX */

The proper way to do this is:
#define _POSIX_C_SOURCE 200112L
#include <time.h>
This method indicates explicitly the features that a source file requires, making it self-contained. It is also portable to any POSIX system using any compiler. No special compiler flag is needed.
With GCC this code will compile with -std=c89, -std=c99, or any other value. Importantly what -std=gnu?? enables by default might differ depending on version or platform.
See Feature Test Macros for details.

Actually, gmtime_r is not part of the ISO C99 standard, it’s a POSIX extension. To enable that, use std=gnu99 standard.
You can always verify which features are available for which standard on your system by applying technique from this Pixelbeat article:
It can be quite confusing sometimes to know exactly
what is #defined in your program, and this is especially
true for glibc's "feature" macros. These macros are documented
(info libc "feature test macros"), but it's much easier
to see what's defined directly using "cpp -dD" like:
$ echo "#include <features.h>" | cpp -dN | grep "#define __USE_"
#define __USE_ANSI
#define __USE_POSIX
#define __USE_POSIX2
#define __USE_POSIX199309
#define __USE_POSIX199506
#define __USE_MISC
#define __USE_BSD
#define __USE_SVID
$ echo "#include <features.h>" | cpp -dN -std=c99 | grep "#define __USE_"
#define __USE_ANSI
#define __USE_ISOC99
Also to see all the predefined macros one can do:
$ cpp -dM /dev/null
Note also for compiler specific macros you can do:
$ gcc -E -dM - < /dev/null

Related

How does my compiler find the stat (file status) function?

I have the following C program:
#include <sys/stat.h>
int main(int argc, char **argv) {
struct stat fileStat;
if(stat(argv[1],&fileStat) < 0)
return 1;
}
When I compile it to LLVM IR using Clang, I can see that stat is declared as following:
declare i32 #stat(i8*, %struct.stat*)
Usually, such an external call to a system function directly maps to a C standard library function. For example, I can find malloc with the following:
nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep malloc
However, the stat function seems to be treated differently. When grepping for stat, I can find related functions such as __xstat but not the stat function itself.
When I trace the call to the external library with ltrace I see the following call: __xstat(1, ".", 0x7fff7928c6f0). Also the code in the executable confirms that instead of calling the stat function the __xstat function is called.
I did not observe other function calls to the C standard library that have other names than those declared in the C program. Why is there no direct equivalent in the standard library and how does my compiler find out that it should produce a call to __xstat and not to stat?
Header sys/stat.h defines stat as a macro that calls __xstat in glibc:
#define stat(fname, buf) __xstat (_STAT_VER, fname, buf)
I found the following comment in /usr/include/x86_64-linux-gnu/sys/stat.h:
/* To allow the `struct stat' structure and the file type `mode_t'
bits to vary without changing shared library major version number,
the `stat' family of functions and `mknod' are in fact inline
wrappers around calls to `xstat', `fxstat', `lxstat', and `xmknod',
which all take a leading version-number argument designating the
data structure and bits used. <bits/stat.h> defines _STAT_VER with
the version number corresponding to `struct stat' as defined in
that file; and _MKNOD_VER with the version number corresponding to
the S_IF* macros defined therein. It is arranged that when not
inlined these function are always statically linked; that way a
dynamically-linked executable always encodes the version number
corresponding to the data structures it uses, so the `x' functions
in the shared library can adapt without needing to recompile all
callers. */
# ifdef __REDIRECT_NTH
extern int __REDIRECT_NTH (stat, (const char *__restrict __file,
struct stat *__restrict __buf), stat64)
__nonnull ((1, 2));
# endif
__REDIRECT_NTH is defined in /usr/include/x86_64-linux-gnu/sys/cdefs.h:
/* __asm__ ("xyz") is used throughout the headers to rename functions
at the assembly language level. This is wrapped by the __REDIRECT
macro, in order to support compilers that can do this some other
way. When compilers don't support asm-names at all, we have to do
preprocessor tricks instead (which don't have exactly the right
semantics, but it's the best we can do).
Example:
int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */
#if defined __GNUC__ && __GNUC__ >= 2
# define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias))
# ifdef __cplusplus
# define __REDIRECT_NTH(name, proto, alias) \
name proto __THROW __asm__ (__ASMNAME (#alias))
# define __REDIRECT_NTHNL(name, proto, alias) \
name proto __THROWNL __asm__ (__ASMNAME (#alias))
# else
# define __REDIRECT_NTH(name, proto, alias) \
name proto __asm__ (__ASMNAME (#alias)) __THROW
# define __REDIRECT_NTHNL(name, proto, alias) \
name proto __asm__ (__ASMNAME (#alias)) __THROWNL
# endif
# define __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
# define __ASMNAME2(prefix, cname) __STRING (prefix) cname
From the comments and macro definitions it seems that the alias is specified in inline assembler.

What is an equivalent of 'unlocked' I/O functions in C99?

When I use --std=c99 GCC defines __STRICT_ANSI__ and when it is on, the BSD and System V features don't kick in. It implies __USE_MISC and __USE_POSIX are left undefined.
-- stdio.h --
...
#if defined __USE_POSIX || defined __USE_MISC
extern int getc_unlocked (FILE *__stream);
extern int getchar_unlocked (void);
#endif /* Use POSIX or MISC. */
...
In the result, functions that I would like to use are omitted. My question is how can I realize I/O operations on standard streams in C99 but without locking ?
Use -std=gnu99 instead of -std=c99 and it will work the way you want.
POSIX actually says that all portable programs should define macro _POSIX_C_SOURCE with version of the Posix standard they want the headers to adher to, prior to including any headers. Thus:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>

Implicit declaration of scandir; alphasort is undeclared

I am trying to use scandir to print a list of files in the current directory. When I try to compile, I am receiving the following errors and warnings:
warning: implicit declaration of function ‘scandir’ [-Wimplicit-function-declaration]
error: ‘alphasort’ undeclared (first use in this function)
note: each undeclared identifier is reported only once for each function it appears in
I am including <dirent.h>, which to my knowledge should define scandir() and all related functions. And I don't see any errors in my code:
#include <dirent.h>
...
int printFiles(){
struct dirent **nameList;
int numOfFiles = scandir(".", &nameList, 0, alphasort);
//TODO print file names
return numOfFiles;
}
....
I am running Ubuntu 12.04, and I'm compiling using gcc with the -c99 flag.
Am I simply overlooking something? I can't figure out why it's failing to compile.
If you use -std=c99, only functions that are strictly a part of the C99 standard are included by the header files. scandir() is not in the C99 standard. Therefore, you have to set a preprocessor variable to ensure that the function prototype is included. For example, the man page for scandir() indicates that setting the _BSD_SOURCE or _SVID_SOURCE preprocessor variables before you do the #include will fix the problem. Or, you can use #define _GNU_SOURCE which will in turn set quite a few different variables for you (including _BSD_SOURCE and _SVID_SOURCE).
Your code will still compile with the warning and work because C allows you to compile with implicitly defined functions, and the linker will correctly link the call to scandir() to the proper function.
what macro you use is decided by the macro in dirent.h on your own computer.usually it located in /usr/include/dirent.h.
find scandir in dirent.h ,you will find the macro which make scandir Invisible.for example in my conmputer,it is "__USE_BSD ,__USE_MISC".
#if defined __USE_BSD || defined __USE_MISC
/* Return the file descriptor used by DIRP. */
extern int dirfd (DIR *__dirp) __THROW __nonnull ((1));
# if defined __OPTIMIZE__ && defined _DIR_dirfd
# define dirfd(dirp) _DIR_dirfd (dirp)
# endif
# ifndef MAXNAMLEN
/* Get the definitions of the POSIX.1 limits. */
# include <bits/posix1_lim.h>
/* `MAXNAMLEN' is the BSD name for what POSIX calls `NAME_MAX'. */
# ifdef NAME_MAX
# define MAXNAMLEN NAME_MAX
# else
# define MAXNAMLEN 255
# endif
# endif
# define __need_size_t
# include <stddef.h>
# ifndef __USE_FILE_OFFSET64
extern int scandir (__const char *__restrict __dir,
struct dirent ***__restrict __namelist,
int (*__selector) (__const struct dirent *),
int (*__cmp) (__const void *, __const void *))
__nonnull ((1, 2));
# else
# ifdef __REDIRECT
extern int __REDIRECT (scandir,
(__const char *__restrict __dir,
struct dirent ***__restrict __namelist,
int (*__selector) (__const struct dirent *),
int (*__cmp) (__const void *, __const void *)),
scandir64) __nonnull ((1, 2));
# else
# define scandir scandir64
# endif
# endif
you know what to do now? don't be worry!it not a nice way to #define this macro directly.
open file features.h(located /usr/include/features.h),search "__USE_MISC" inside,you can see codes below:
#if defined _BSD_SOURCE || defined _SVID_SOURCE
# define __USE_MISC 1
#endif
it tells that if"_BSD_SOURCE "or"_SVID_SOURCE"is defined,then __USE_MISC would be defined auto.
consider Compatibility of you own codes,add statement below(any one or both) at start(before any statement like #include <.h>||".h") of you file which will use scandir().
#define _BSD_SOURCE 1
#define _SVID_SOURCE 1
save your file and make.
try to #include <sys/dir.h> file to use scandir and define extern int alphasort(const void*,const void*); or extern int alphasort(); above your printFiles
also - you should link you program with standard library (hope it is already done)

Why is _GNU_SOURCE macro required for pthread_mutexattr_settype() while it is in POSIX/IEEE standard?

I have written a multithread server program in C, which echoes back all the data that a client sends.
Initially, I used poll() function in my program to detect POLLRDHUP event, for that I defined _GNU_SOURCE macro (This event is defined here).
Later I updated my code & removed poll() function, however I forgot to remove _GNU_SOURCE macro.
Now my code is finally complete (and a little long to post, more than 250 lines). Before removing macro I was compiling my program using:
gcc multi_thread_socket_v4.c -Wall -Werror -g -lpthread -o multi_thread_socket
and it worked fine: No errors, no warnings
After I removed the macro definition, and compiled using same command-line, the output of gcc was:
multi_thread_socket_v4.c: In function ‘main’:
multi_thread_socket_v4.c:194: warning: implicit declaration of function ‘pthread_mutexattr_settype’
multi_thread_socket_v4.c:194: error: ‘PTHREAD_MUTEX_ERRORCHECK’ undeclared (first use in this function)
multi_thread_socket_v4.c:194: error: (Each undeclared identifier is reported only once
multi_thread_socket_v4.c:194: error: for each function it appears in.)
I have included all the required libraries as it worked fine initially.
I peeked into pthread.h at /usr/include/pthread.h and found out this:
/* Mutex types. */
enum
{
PTHREAD_MUTEX_TIMED_NP,
PTHREAD_MUTEX_RECURSIVE_NP,
PTHREAD_MUTEX_ERRORCHECK_NP,
PTHREAD_MUTEX_ADAPTIVE_NP
#ifdef __USE_UNIX98
,
PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
#endif
#ifdef __USE_GNU
/* For compatibility. */
, PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
#endif
};
and this:
#ifdef __USE_UNIX98
/* Return in *KIND the mutex kind attribute in *ATTR. */
extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict
__attr, int *__restrict __kind)
__THROW __nonnull ((1, 2));
/* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
PTHREAD_MUTEX_DEFAULT). */
extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
__THROW __nonnull ((1));
I checked out here to check if __USE_UNIX98 is a feature test macro, but it was not there.
So please help me understanding the reasons for the error, because the function & the macro where gcc shows error are defined in POSIX standard. I do not know what more info regarding my problem will be required so please tell me, I will update my question.
You should use
#define _POSIX_C_SOURCE 200112L
if you want to use POSIX features such as pthread_mutexattr_settype ... see http://pubs.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_02.html
Another possibility is
#define _XOPEN_SOURCE 700
See http://man7.org/linux/man-pages/man7/feature_test_macros.7.html and http://pubs.opengroup.org/onlinepubs/9699919799/
Setting _GNU_SOURCE includes POSIX and lots of other definitions.
P.S. I would expect that including <pthread.h> includes <features.h>, which by default defines _POSIX_C_SOURCE as 200112L, but it's possible that you have defined something that overrides that ... see /usr/include/features.h on your system for details of the symbols and their usage.
It doesn't, your problem likely lies elsewhere.
I just compiled a trivial program with the following content:
#include <pthread.h>
int main(int argc, char **argv)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
return 0;
}
This compiles perfectly with gcc -pthread -Wall -Werror a.c.
It's possible that another part of your program causes this, by eg. doing something silly like defining _PTHREAD_H, or some other minor sabotage.
You might want to try to get a minimal test case by using a tool like delta or creduce, which will probably make the problem evident.
When you're using old libraries (e.g. 2.1.x) you should use
#define __USE_UNIX98
Using a macro beginning with "__" it's not usually a good idea, but sometimes it's the only way... see also this discussion

Why do I get in my timespec-array the error "array type has incomplete element type"?

I got a problem with my C-Code in Eclipse. To be specific my sleep-method does produce an error in the line where the timespec is stated. May you guys can tell me what I did wrong? Here's the code:
void sleep(double time) {
nanosleep(
(struct timespec[]) { {time,((time -((time_t)time)) * 1000000000)}},
NULL);
}
You need to include the header file which defines the type timespec. Either:
You forgot to include the header file or
You merely forward declared the type.
Second seems the most likely cause of error. Since you are creating an array, the compiler needs to know the definition of timespec as it needs to allocate that much memory for the array.
The problem is that struct timespec and nanosleep() are not defined in the C standard. They are provided by POSIX standard. It seems you are compiling with -std=c99 or so which makes your compiler to strictly adhere to the C99 standard and hence report errors. To be able to compile these POSIX constructs you will have to explicitly enable them.
Compilation with std=c99
Compilation after enabling POSIX definitions:
#if __STDC_VERSION__ >= 199901L
# define _XOPEN_SOURCE 600
#else
# define _XOPEN_SOURCE 500
#endif /* __STDC_VERSION__ */
#include <time.h>
int main()
{
double time = 0.1;
nanosleep((struct timespec[]) { {time, ((time - ((time_t)time)) *
1000000000)}}, NULL);
return 0;
}
__STDC_VERSION__ checks if the compiler you are using is c99 & depending on the compiler it enables the POSIX definitions.
_XOPEN_SOURCE defines which version of POSIX you want to refer to. Select the definition as per the POSIX version you use. 600 refers to POSIX 2004 while 500 refers to POSIX 1995.

Resources