Using strdup in C11 - c

I am able to compile the following using gcc version 4.7.2
#include <string.h>
int main(){
char text[] = "String duplicate";
char* dup = strdup(text);
return 0;
}
But when I used the --std=c11 flag, I get the following warning:
warning: implicit declaration of function ‘strdup’ [-Wimplicit-function-declaration]
warning: initialization makes pointer from integer without a cast [enabled by default]
What changed to cause this warning?

Read the manual of strdup by
man strdup
You can find that
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
strdup():
_SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
It denotes that strdup conforms to SVr4, 4.3BSD, POSIX.1-2001.
So you can get rid of the warnings by
gcc -D_BSD_SOURCE -std=c11 <your source file>
I guess the warnings are caused by c11 not enabling one of the above macros.

you want --std=gnu11 or --std=c11 -D_GNU_SOURCE

Related

Why does -std=c11 with gcc hide popen in stdio.h? [duplicate]

This question already has answers here:
popen implicitly declared even though #include <stdio.h> is added
(3 answers)
Closed 4 years ago.
I want to use popen. It is in stdio.h. I include that, but the compiler doesn't see it with
-std=c11. It does compile without -std=c11.
#include <stdio.h>
int main(void)
{
popen("ls *","r");
}
gcc -std=c11 popen_test.c
popen_test.c: In function ‘main’:
popen_test.c:5:4: warning: implicit declaration of function ‘popen’ [-Wimplicit-function-declaration]
popen("ls *","r");
^~~~~
It is hidden in stdio.h with
#ifdef __USE_POSIX2
The man page says it is available if:
_POSIX_C_SOURCE >= 2 || /* Glibc versions <= 2.19: */
_BSD_SOURCE || _SVID_SOURCE
popen is not part of C. To get it, you need to enable it with a feature test macro before including anything.
The simplest way to do it is with a #define _GNU_SOURCE at the top (or with -D_GNU_SOURCE in your compiler invocation).
compiles with -std=c11:
#define _GNU_SOURCE
#include <stdio.h>
int main(void)
{
popen("ls *","r");
}

warning: implicit declaration of function 'daemon'

I get this warning while compiling my program. daemon() is declared in unistd.h and its included. How to fix this or make it disappear?
error:
dcron.c: In function 'main':
dcron.c:35:4: warning: implicit declaration of function 'daemon' [-Wimplicit-function-declaration]
if (daemon(1, 0) != 0) {
^
part of program:
if (daemon(1, 0) != 0) {
fprintf(stderr, "error: failed to daemonize\n");
syslog(LOG_NOTICE, "error: failed to daemonize");
return 1;
}
setup:
gcc4.8.2, glibc2.19
CFLAGS=-std=c99 -Wall -Wpedantic -Wextra
You need to add the relevant header file and enable the _BSD_SOURCE feature test macro:
#define _BSD_SOURCE
#include <unistd.h>
From man 3 daemon:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
daemon(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)
On Linux daemon() is made available by #defineing either
_XOPEN_SOURCE
_BSD_SOURCE
by doing
#define _XOPEN_SOURCE
or
#define _BSD_SOURCE
before #includeing
#include <unistd.h>
or by adding -D _XOPEN_SOURCE or -D _BSD_SOURCE to the compilation command.

be64toh not linking or being declared when compiling with -std=c99

When I compile the following program (the code for all the defines I've gotten from 64 bit ntohl() in C++? which seemed sensible):
#include <stdint.h>
#if defined(__linux__)
#include <endian.h> //htobe64,be64toh
#include <arpa/inet.h> //ntohs, ntohl, htonl, htons
#elif defined(__FreeBSD__) || defined(__NetBSD__)
#include <sys/endian.h>
#elif defined(__OpenBSD__)
#include <sys/types.h>
#define be16toh(x) betoh16(x)
#define be32toh(x) betoh32(x)
#define be64toh(x) betoh64(x)
#endif
int main()
{
int64_t i = 0x1212121234343434;
int64_t j = be64toh(i);
return 0;
}
I get a linking error when compiling it with the following command (I'm running linux):
gcc -std=c99 endian_test.c -o endian
The error i receive is:
user#host ~/src/c $ gcc -std=c99 derp.c
endian_test.c: In function ‘main’:
endian_test.c:17:2: warning: implicit declaration of function ‘be64toh’ [-Wimplicit-function-declaration]
int64_t j = be64toh(i);
^
/tmp/ccYonfH4.o: In function `main':
endian_test.c:(.text+0x23): undefined reference to `be64toh'
collect2: error: ld returned 1 exit status
Which to me indicates two things, the header itself is included but doesn't really contain the functions/macros needed for this to work and because that means the compiler hopes it's gonna find the function later it tries to go ahead anyway but fails when trying to link.
But if i use the following command to compile (just remove -std=c99):
gcc endian_test.c -o endian
Everything is smooth as butter and works. Any idea why it's happening and what i could do to remedy it? To me it doesn't make sense that functions given by the kernel (or am i mistaken in that fact?) change depending on what standard i use when compiling?
Thanks in advance!
Without explicit -std= option, calling gcc is the same as -std=gnu89 with means C89 + GNU extensions. The GNU extensions will enable macros which will enable the presence of the functions in your header.
If you see the be64toh manual, you will see that it needs the _BSD_SOURCE to be defined. So on Linux #define it before you include <endian.h>.
I had this problem. The solution was to declare not only
#define _BSD_SOURCE
but also
#define __USE_BSD
https://github.com/tailhook/zerogw/pull/34/files#r32008569
Recent changes to glibc has meant you need
#define _DEFAULT_SOURCE
instead of
#define _BSD_SOURCE
Deprecation of _BSD_SOURCE and _SVID_SOURCE feature macros

stdlib.h doesn't have declaration for putenv

I've tried compiling the following code with gcc 4.7.3 and clang 3.2.1 on Ubuntu 13.04 (64-bit):
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main() {
putenv("SDL_VIDEO_CENTERED=1");
return 0;
}
I expected putenv to be declared in the stdlib.h header, but I get the following warning:
test.c: In function ‘main’:
test.c:6:5: warning: implicit declaration of function ‘putenv’ [-Wimplicit-function-declaration]
Why is the declaration for this function missing in my header?
You have to define certain macros. Look at man 3 putenv:
NAME
putenv - change or add an environment variable
SYNOPSIS
#include <stdlib.h>
int putenv(char *string);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
putenv(): _SVID_SOURCE || _XOPEN_SOURCE
Try defining either _SVID_SOURCE or _XOPEN_SOURCE before including stdlib.h, like so:
#define _XOPEN_SOURCE
#include <stdlib.h>
Or when compiling (with -D), like:
gcc -o output file.c -D_XOPEN_SOURCE

Constants not loaded by compiler

I started studying POSIX timers, so I started also doing some exercises, but I immediately had some problems with the compiler.
When compiling this code, I get some strange messages about macros like CLOCK_MONOTONIC. Those are defined in various libraries like time.h etc. but the compiler gives me errors as if they are not defined.
It is strange because I am using a Fedora 16, and some of my friends with Ubuntu get less compiler errors than I :-O
I am compiling with gcc -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -lrt
Here the errors I get:
struct sigevent sigeventStruct gives:
storage size of ‘sigeventStruct’ isn’t known
unused variable ‘sigeventStruct’ [-Wunused-variable]
Type 'sigevent' could not be resolved
unknown type name ‘sigevent’
sigeventStruct.sigev_notify = SIGEV_SIGNAL gives:
‘SIGEV_SIGNAL’ undeclared (first use in this function)
request for member ‘sigev_notify’ in something not a structure or union
Field 'sigev_notify' could not be resolved
if(timer_create(CLOCK_MONOTONIC, sigeventStruct, numero1) == -1) gives:
implicit declaration of function ‘timer_create’ [-Wimplicit-function- declaration]
‘CLOCK_MONOTONIC’ undeclared (first use in this function)
Symbol 'CLOCK_MONOTONIC' could not be resolved
Here is the code:
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
int main()
{
timer_t numero1;
struct sigevent sigeventStruct;
sigeventStruct.sigev_notify = SIGEV_SIGNAL;
if(timer_create(CLOCK_MONOTONIC, sigeventStruct, numero1) == -1)
{
printf( "Errore: %s\n", strerror( errno ) );
}
return 0;
}
Firstly, you can compile your code with -std=gnu99 instead of -std=c99 if you want to have the identifiers SIGEV_SIGNAL, sigeventStruct, and CLOCK_MONOTONIC available.
As noted by #adwoodland these identifiers are declared when _POSIX_C_SOURCE is set to a value >= 199309L, which is the case with -std=gnu99. You can also use -D_POSIX_C_SOURCE=199309L -std=c99 or have the macro defined in source code.
Secondly, see the timer_create prototype, you have to pass pointers as the second and the third argument to the function:
timer_create(CLOCK_MONOTONIC, &sigeventStruct, &numero1)
^ ^
Also you have to include the standard header string.h for strerror function declaration.
If you are using -std=c99 you need to tell gcc you're still using recent versions of POSIX:
#define _POSIX_C_SOURCE 199309L
before any #include, or even with -D on the command line.
Other errors:
Missing #include <string.h>
You need a pointer for timer_create, i.e. &sigeventStruct instead of just sigeventStruct
The other answers suggest _POSIX_C_SOURCE as the enabling macro. That certainly works, but it doesn't necessarily enable everything that is in the Single Unix Specification (SUS). For that, you should set _XOPEN_SOURCE, which also automatically sets _POSIX_C_SOURCE. I have a header I call "posixver.h" which contains:
/*
** 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 */
It is tuned for the systems I work with which don't all recognize the 700 value. If you are working on a relatively modern Linux, I believe you can use 700. It's in a header so that I only have to change one file when I want to alter the rules.
Referring to the CLOCK_MONOTONIC not being defined problem:
As Caterpillar pointed out this is an eclipse bug, more precisely a CDT-Indexer bug with a workaround at eclipse bugs, comment 12
I solved a lot of problems with -std=gnu99 (without specifing any POSIX versions) but I am still having
CLOCK_MONOTONIC could not be resolved
Searching on internet I found some Eclipse bugreports with people complaining about this. Have to check better if is an Eclipse bug, because with
gcc -Wall -w -o Blala timer.c -std=gnu99 -lrt
it compiles

Resources