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"
Related
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.
I've created a c project and this is the beginning of the main.c file:
#include <curl/curl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "include/httpdef.h"
//...some code
The httpdef.h beginning is this:
#ifndef httpdef
#define httpdef
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>
//definitions
#endif
At the very first line of both files I get the error from the gcc compiler:
macro name must be an identifier
What could be the problem?
EDIT: I realized now that actually the compiler doesn't give any error, it's my vim plugin (YouCOmpleteMe) that generates this error. If I compile everything works and the error doesn't appear
I get an error message error: ‘SIG_BLOCK’ undeclared for this code when compiling with -ansi.
sigprocmask(SIG_BLOCK, &my_sig, NULL);
Did I forget to be explicit about some header file? These are my includes
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
You need to tell the compiler you want SIG_BLOCK to be defined.
From man sigaction:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
sigprocmask(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
So you might like to pass the option
-D_POSIX_SOURCE
or
-D_POSIX_C_SOURCE=1
to gcc for example
Alternativly you can put those "requests" as preprocessor directives right at the top of your sources:
#define _POSIX_SOURCE
... /* other includes */
#include <signal.h>
or
#define _POSIX_C_SOURCE 1
... /* other includes */
#include <signal.h>
So I have quite a lot of .c and .h files in my project:
Here are just the headers of the files that are having an issue:
#ifndef OUTPUTUTILITIES_H
#define OUTPUTUTILITIES_H
#include <string.h>
#include <stdio.h>
#include "parser.h" // <== IF I REMOVE THIS include everything works. But I need to include this here
#endif
#ifndef PARSER_H
#define PARSER_H
#include <stdbool.h>
#include <stdio.h>
#include "utilities.h"
#endif
#ifndef UTILITIES_H
#define UTILITIES_H
#include <string.h>
#include <stdio.h>
#include "variableVector.h"
#endif
#ifndef VARIABLEVECTOR_H
#define VARIABLEVECTOR_H
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#endif
Can someone please explain why I cannot #include "parser.h" file in my outputUtilites.h file? And also what are the general principles behind organizing your import .h files?
I also wanted to let you know that in the corresponding .c file I only include the corresponding .h file and nothing else. For example in my parser.c file I ONLY include parser.h and in my ouputUtilities.c file I ONLY include outputUtilities.h file.
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.