std18 getpagesize : implicit declaration of function + nested extern declaration - c

I don't understand why the function getpagesize gives me a warning for implicit declaration of function while using the c18 version of gcc.
gcc test.c -Wall -std=c18
implicit declaration of function ‘getpagesize’ [-Wimplicit-function-declaration]
nested extern declaration of ‘getpagesize’ [-Wnested-externs]
int BLOCKSIZE = getpagesize();
And this is my included files :
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdint.h>
#include <errno.h>

Using -std=cXX instead of -std=gnuXX disables a bunch of normally defined feature test macros, including the ones that provide getpagesize(). From its man page (Assuming you're using linux):
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
getpagesize():
Since glibc 2.19:
_DEFAULT_SOURCE || ! (_POSIX_C_SOURCE >= 200112L)
From glibc 2.12 to 2.19:
_BSD_SOURCE || ! (_POSIX_C_SOURCE >= 200112L)
Before glibc 2.12:
_BSD_SOURCE || _XOPEN_SOURCE >= 500
So you have to define the appropriate one to the appropriate value before including any header files. Or just use -std=gnu18.
Edit: Also, since getpagesize() is obsolete and not standard, consider using the POSIX standard sysconf(_SC_PAGESIZE) instead.

Related

Weird behavior with defines for usleep() and inet_aton()

I have created two modules: files.h and connection.h.
files.h is included in connection.h.
files.h uses usleep() function and connection.h uses inet_aton() function at some point of the respective .c files. Those functions need the following defines:
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
So, as files.h is included in connection.h, I thought I could just write those defines in files.h but when I compile I get the following error:
connection.c:23:6: error: implicit declaration of function ‘inet_aton’
So I decided to try to write those defines in connection.h instead of files.h just to compile and get the following error:
files.c:298:3: error: implicit declaration of function ‘usleep’
At this point, my next option was writing the defines in the respective .c files to solve this. But instead, I got this error while compiling:
files.c:302:3: error: implicit declaration of function ‘usleep’
connection.c:23:6: error: implicit declaration of function ‘inet_aton’
I don't understand what's the issue. How can I use both functions?
files.h
#ifndef _FILES_H_
#define _FILES_H_
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
// ...
#endif
connection.h
#ifndef _CONNECTION_H_
#define _CONNECTION_H_
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "files.h"
#include <ctype.h>
#include <pthread.h>
// ...
#endif
This seems to be an ordering issue..
When you include in this way:
#include <unistd.h> // other includes as well
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
The header files are brought in without the override defines.
However, the purpose of the defines is to change what functions/signatures are imported from the headers!
And since C is very linear, the order matters..
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
#include <unistd.h> // other includes as well
Basically, define your requests first, before you include any standard header file.
These must be included before the FIRST TIME the header is seen -
So if 'connection.c' includes something before connection.h, then the defines may not be present for the first include of <unistd.h>
I finally solved this issue writing the defines above the includes thanks to your suggestions BUT in the .c files. Still not working if I write the defines anywhere in the .h files.
files.c
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
#include "files.h"
connection.c
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
#include "connection.h"

Implicit declaration of function ‘mknod’ but I have the headers included

I am trying to make a C program that uses named pipes to communicate with a C++ program on a Raspberry Pi 3.
The warning that GCC is spitting out when I compile some code of mine:
/home/pi/BluetoothTest/btooth.c|76|warning: implicit declaration of function ‘mknod’ [-Wimplicit-function-declaration]|
Here is the code from for the function, including the #if above it:
#if defined __USE_MISC || defined __USE_BSD || defined __USE_XOPEN_EXTENDED
extern int mknod (const char *__path, __mode_t __mode, __dev_t __dev)
__THROW __nonnull ((1));
and here are the includes that I have in the file:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>
//#include <linux/stat.h>
The program attempts to create the pipe here:
umask(0);
fifo = mknod(PIPE_LOC, S_IFIFO|0666, 0);
fp = fopen(PIPE_LOC, "w");
fifo is an int that isn't used anywhere else and fp is a FILE* to the pipe. Some debugging that I have done shows that fifo has a value of -1 after mknod runs, likely because of the compiler not seeming to be able to find the implementation of the function.
How do I make it so that GCC knows where to find the implementation of mknod?
As you can see that for declaration of mknod() function to stay after preprocessing stage, one of three macros (__USE_MISC, __USE_BSD, __USE_XOPEN_EXTENDED) should be defined. Otherwise, declaration of mknod() will be removed during preprocessing stage.
#if defined __USE_MISC || defined __USE_BSD || defined __USE_XOPEN_EXTENDED
extern int mknod (const char *__path, __mode_t __mode, __dev_t __dev)
__THROW __nonnull ((1));
You can use compiler options: -std=gnu99 -D_GNU_SOURCE or you can define these macros on your own and place them above header file inclusion.
I think you're missing a definition of some feature test macro required for the respective headers to define mknod. According to the Linux Programmer's Manual for the function (man 2 mknod) the macros for glibc are:
mknod():
_XOPEN_SOURCE >= 500
|| /* Since glibc 2.19: */ _DEFAULT_SOURCE
|| /* Glibc versions <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE
Try adding -D_XOPEN_SOURCE=500 to your compile flags to see if that helps.

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

implicit declaration using -std=c99

I'm getting this warning: (-std=c99 -pedantic)
warning: implicit declaration of function ‘strndup’ [-Wimplicit-function-declaration]
but I'm importing these libs:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
So what?! :(
// file.c:
#include "file.h"
strndup(...)
// file.h:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
The issue is your usage of the -std=c99 option. Since strndup() isn't part of C99, and you're asking the compiler to go into standards compliant mode, it won't provide the prototype for it. It still links of course, because your C library has it.
While you may be able to coax gcc into providing it by specifying feature macros yourself, I'd say it doesn't make much sense to be in C99 compliance mode and ask for GNU extensions for example. gcc already provides a mode for this, which will solve your warning: -std=gnu99.
My man strndup says
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
strndup():
Since glibc 2.10:
_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
Before glibc 2.10:
_GNU_SOURCE
strdupa(), strndupa(): _GNU_SOURCE
So I'd need to, eg, #define _POSIX_C_SOURCE 200809L before the first #include in your file.
see man 7 feature_test_macros
strndup is a GNU extension, so you need to compile with -D_GNU_SOURCE on the command line, or stick a #define _GNU_SOURCE 1 in your source files before the #include lines
This happened to me, and I added #define _XOPEN_SOURCE 500 and the warning went away.

popen implicitly declared even though #include <stdio.h> is added

This is tiny snippet of my code.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
...
FILE * pipe;
...
pipe = popen ("ls /tmp -1", "r");
...
pclose(pipe);
blarg.c:106: warning: implicit declaration of function ‘popen’
blarg.c:106: warning: assignment makes pointer from integer without a cast
blarg.c:112: warning: implicit declaration of function ‘pclose’
blarg.c:118: warning: assignment makes pointer from integer without a cast
I'm really unsure. I looked up popen and all it requires is stdio.h which is provided. What is missing, or is the problem in the rest of my code (I don't really want to show more code because its an a assignment).
As the man page says:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
popen(), pclose(): _POSIX_C_SOURCE >= 2 || _XOPEN_SOURCE || _BSD_SOURCE
|| _SVID_SOURCE
So you should #define _BSD_SOURCE or one of the others before #includeing stdio.h.
Replace -std=c99 or -std=c11 etc with -std=gnu99 or -std=gnu11.
I put the prototypes of popen and pclose at the top of my code. It seemed to have settled the problem.

Resources