HOST_NAME_MAX undefined after include <limits.h> - c

I don't know why it still says HOST_NAME_MAX is implicit declaration.
Instead, I searched the web and do the following to fix it:
#include <netdb.h>
and use MAXHOSTNAMELEN instead of HOST_NAME_MAX
however, I am not very sure it this is a good way, and the reasons behind it.

Using grep:
$ grep -rl '#define HOST_NAME_MAX' /usr/include
We can see that HOST_NAME_MAX is defined in:
/usr/include/bits/local_lim.h
And local_lim.h is included by /usr/include/bits/posix1_lim.h:
# grep -rl local_lim.h /usr/include
/usr/include/bits/posix1_lim.h
And posix1_lim.h is included by limits.h only if __USE_POSIX is defined:
#ifdef __USE_POSIX
/* POSIX adds things to <limits.h>. */
# include <bits/posix1_lim.h>
#endif
So if your code looks like:
#define __USE_POSIX
#include <limits.h>
You should have the HOST_NAME_MAX constant available. Having said that, on my system __USE_POSIX appears to be defined by default. For example, the following code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
int main(int argc, char **argv) {
#ifdef __USE_POSIX
printf("__USE_POSIX is defined\n");
#endif
printf("HOST_NAME_MAX: %d\n", HOST_NAME_MAX);
return 0;
}
Prints:
__USE_POSIX is defined
HOST_NAME_MAX: 64

Related

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.

Compiling C with non standard header

I have my main C file:
#if defined(WIN32)
#include <windows.h>
#include <stddef.h>
#endif
#if defined(LINUX)
#include <curses.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(WIN32)
#include <conio.h>
#endif
#include <ctype.h>
#include <a429usbnt.h>
#if defined(WIN32)
#include "genlib.h"
#endif
void main()
{
_open_xpc(1);
}
When I try to compile using this command
gcc -I. -L. test.c -o test
I get the following error: undefined reference to '_open_xpc'.
However if I change the call to the _open_xpc function and instead just
printf("%d", XPC_ERROR_ACTIONCODE);
the program compiles fine and the correct value assigned to the definition of XPC_ERROR_ACTIONCODE is printed out, so the compiler is linking a429usbnt.h but will only recognize defined variables and not the functions.
If you are trying to link against a .lib file with gcc, it seems you need to define a directory with -L and an actual file with -l

Cannot access ifreq structure definition, __USE_MISC macro undefined

I am trying to compile the following single C file (called main.c):
#include <stdio.h>
#define __USE_MISC 1
#include <net/if.h>
int main(int argc, char **argv)
{
ifreq id_ifreq;
fprintf(stdout, ">>>>>> OK <<<<<<\n");
}
... using "gcc main.c -o main". I get the following error:
main.c: In function ‘main’:
main.c:9:2: error: unknown type name ‘ifreq’
I know that "ifreq" structure definition lies within a "#ifdef __USE_MISC" macro, however, I cannot activate that block of code.
I developed the following code for checking which MACROS are defined (compiled with "gcc main.c -o main"):
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <net/if.h>
int main(int argc, char **argv)
{
#ifdef __USE_MISC
printf("__USE_MISC defined\n");
#endif
#ifdef _GNU_SOURCE
printf("_GNU_SOURCE defined\n");
#endif
#ifdef _BSD_SOURCE
printf("_BSD_SOURCE defined\n");
#endif
#ifdef _SVID_SOURCE
printf("_SVID_SOURCE defined\n");
#endif
}
The result is that they are all defined but the "_GNU_SOURCE" one. However, I am still not capable of using the definition of the "ifreq" structure included in the "net/if.h" file.
Anybody can help?
You are omitting the struct keyword (in C, a struct definition is not a typedef)
#include <stdio.h>
#include <net/if.h>
int main(int argc, char **argv)
{
struct ifreq id_ifreq;
fprintf(stdout, ">>>>>> OK <<<<<<\n");
return 0;
}

gcc compile time type resolution

I have three files, say A.c , B.c and C.c, all of which #include common.h
In common.h, I include "sys/socket.h" and I protect the common.h by macros:
#ifndef __COMMON_H
#define __COMMON_H
// body of file goes here
#endif
When i compile the code, I get several errors such as below
In file included from /usr/include/sys/socket.h:40,
from tcpperf.h:4,
from wrapunix.c:1:
/usr/include/bits/socket.h:425: error: conflicting types for 'recvmmsg'
/usr/include/bits/socket.h:425: note: previous declaration of 'recvmmsg' was here
In file included from /usr/include/sys/socket.h:40,
from tcpperf.h:4,
from wrapsock.c:1:
As you can see wrapunix.c and wrapsock.c, they both include tcpperf.h, but tcpperf.h is guarded with macros,yet gcc complains that recvmsg was declared multiple times. How do I resolve this issue?
Update:
Here is the header of tcpperf.h, that is causing issues
#ifndef _TCPPERF_H
#define _TCPPERF_H
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include <regex.h>
#include <errno.h>
#include <sched.h>
#include <pthread.h>
#include <argp.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <linux/tcp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/prctl.h>
#include <unistd.h>
#include <sys/wait.h>
#endif
The above error can be reproduced by providing "-combine -fwhole-program" flags to gcc such as
gcc -std=gnu99 -Wall -combine -fwhole-program -I. error.c wrapunix.c wrapsock.c file1.c file2.c -o file2 -lrt
The error is "conflicting types for 'recvmmsg'" rather than just duplicate definition (which would be tolerated if equal). That means your .c source receives two different version of recvmmsg: one by your direct tcpperf.h inclusion and another one by inclusion it via sys/socket.h. I believe you have another version of tcpperf.h elsewhere in inclusion path with different (perhaps older version) recvmmsg.
The problem is almost certainly related to -combine. This is a bit of a guess, but in looking at the definition of recvmmsg:
extern int recvmmsg (int __fd, struct mmsghdr *__vmessages,
unsigned int __vlen, int __flags,
__const struct timespec *__tmo);
note that it takes a struct mmsghdr as an argument. However, while this prototype is unconditional, struct mmsghdr is only defined if __USE_GNU is set:
#ifdef __USE_GNU
/* For `recvmmsg'. */
struct mmsghdr
{
struct msghdr msg_hdr; /* Actual message header. */
unsigned int msg_len; /* Number of received bytes for the entry. */
};
#endif
-combine is basically equivalent to concatenating all your files together and then compiling them. Is there any chance that between the text of wrapunix.c and wrapsock.c that GNU_SOURCE is being defined? If that happened, then the first definition of recvmmsg would use a definition of struct mmsghdr that was local to just the prototype, while the second definition would use the real struct. Those two definitions would then be incompatible, which would result in the error message that you got.

How can I stop #including redundant headers when I use header files like these?

So I'm still getting used to modular programming, and want to make sure I'm adhering to best practices. If I have the two module header files below, will the the headers #included by each file (for example "mpi.h") be included multiple times? Is there a proper way to account for this?
Also, my module headers typically look like these examples, so any other criticism/pointers would be helpful.
/* foo.h */
#ifndef FOO_H
#define FOO_H
#include <stdlib.h>
#include "mpi.h"
void foo();
#endif
and
/* bar.h */
#ifndef BAR_H
#define BAR_H
#include <stdlib.h>
#include "mpi.h"
void bar();
#endif
And use the sample program:
/* ExampleClient.c */
#include <stdlib.h>
#include <stdio.h>
#include "mpi.h"
#include "foo.h"
#include "bar.h"
void main(int argc, char *argv[]) {
foo();
MPI_Func();
bar();
exit(0)
}
What do you mean by 'include'? The preprocessor statement #include file copies the contents of file and replaces the statement with these contents. This happens no matter
If by 'include' you mean "the statements and symbols in these files will be parsed multiple times causing warnings and errors", then no, the include guards will prevent that.
If by 'include' you mean "some part of compiler will read some part of these files", then yes, they'll be included multiple times. The preprocessor will read the second inclusion of the file and replace it with a blank line because of the include guards, which incurs a tiny overhead (the file is already in memory). Modern compilers (GCC, not sure about others) will probably be optimized to avoid this, however, and note that the file has include guards on the first pass and simply discard future inclusions, removing the overhead - Don't worry about speed here, clarity and modularity are more important. Compilation is a time-consuming process, for sure, but #include is the least of your worries.
To better understand include guards, consider the following code sample:
#ifndef INCLUDE_GUARD
#define INCLUDE_GUARD
// Define to 1 in first block
#define GUARDED 1
#endif
#ifndef INCLUDE_GUARD
#define INCLUDE_GUARD
// Redefine to 2 in second block
#define GUARDED 2
#endif
After (the first pass of) preprocessing, what will GUARDED be defined to? The preprocessor statement #ifndef or its equivalent, #if !defined() will return false if their argument is indeed defined. Therefore, we can conclude that the second #ifndef will return false, so only the first definition of GUARDED will remain after the first pass of the preprocessor. Any instance of GUARDED remaining in the program will be replaced by 1 on the next pass.
In your example, you've got something slightly (but not much) more complicated. Expanding all the #include statements in ExampleClient.c will result in the following source: (Note: I indented it, but that's not normal style for headers and the preprocessor won't do it. I just wanted to make it more readable)
/* ExampleClient.c */
//#include <stdlib.h>
#ifndef STDLIB_H
#define STDLIB_H
int abs (int number); //etc.
#endif
//#include <stdio.h>
#ifndef STDLIB_H
#define STDLIB_H
#define NULL 0 //etc.
#endif
//#include "mpi.h"
#ifndef MPI_H
#define MPI_H
void MPI_Func(void);
#endif
//#include "foo.h"
#ifndef FOO_H
#define FOO_H
//#include <stdlib.h>
#ifndef STDLIB_H
#define STDLIB_H
int abs (int number); //etc.
#endif
//#include "mpi.h"
#ifndef MPI_H
#define MPI_H
void MPI_Func(void);
#endif
void foo(void);
#endif
//#include "bar.h"
#ifndef BAR_H
#define BAR_H
//#include <stdlib.h>
#ifndef STDLIB_H
#define STDLIB_H
int abs (int number); //etc.
#endif
//#include "mpi.h"
#ifndef MPI_H
#define MPI_H
void MPI_Func(void);
#endif
void bar(void);
#endif
void main(int argc, char *argv[]) {
foo();
MPI_Func();
bar();
exit(0); // Added missing semicolon
}
Go through that code and note when various definitions are performed. The result is:
#define STDLIB_H
int abs (int number); //etc.
#define STDLIB_H
#define NULL 0 //etc.
#define MPI_H
void MPI_Func(void);
#define FOO_H
void foo(void);
#define BAR_H
void bar(void);
With respect to your request for other criticism/pointers, why are you #including stdlib.h and mpi.h in all your headers? I understand that this is a stripped down example, but in general, header files should only include files necessary for the declaration of their contents. If you use a function from stdlib or call MPI_func() in foo.c or bar.c, but the function declarations are simply void foo(void), you shouldn't include these files in the header function. For example, consider the following module:
foo.h:
#ifndef FOO_H
#define FOO_H
void foo(void);
#endif
foo.c:
#include <stdlib.h> // Defines type size_t
#include "mpi.h" // Declares function MPI_func()
#include "foo.h" // Include self so type definitions and function declarations
// in foo.h are available to all functions in foo.c
void foo(void);
size_t length;
char msg[] = "Message";
MPI_func(msg, length);
}
In this example, the implementation of foo() requires stuff from stdlib and mpi, but the definition does not. If foo() returned or required a size_t value (typedef'ed in stdlib), you'd need to #include stdlib in the .h file.
Mostly no, with a bit 'yes'. Your header files will be 'read' more than once but at second and later time the preprocessor will cut off all the contents. This implies that it won't waste your compiler's time and also #includes inside your #ifdef blocks will be done only once (per header file).
It's a good practice. Myself, I also add the following line before #ifdefs:
#pragma once
When supported by the particular compiler, it guarantees that the file will actually be read only once. I think it's a little bit more optimal that way.
So, to sum up:
header guards like you are using prevent compiler from interpreting the header contents more than once but possibly can cause the preprocessor to parse it more than once (which is not a big problem),
#pragma once causes the particular header file to be read only once.
When using both, #pragma once should be in effect if supported by compiler; if not, header guards will apply.
1) GOOD: you have an "include guard". "stdlib.h", "mpi.h" and "void foo()" are only seen by the compiler the first time you #include "foo.h"
/* foo.h */
#ifndef FOO_H
#define FOO_H
#include <stdlib.h>
#include "mpi.h"
void foo();
#endif
2) BAD: This will #include the entire contents of "foo.h" every time you use it:
/* foo.h */
#include <stdlib.h>
#include "mpi.h"
void foo();
3) By #include", I mean "once per compilation unit" (i.e. the same .c source file).
This mainly "protects" against a header (foo.h) calling another header ("bar.h) which might recursively call the first header.
Every different compilation unit that #includes foo.h will always get "stdlib.h", "mpi.h" and "void foo()". The point is that they'll be seen only once - not multiple times in the same compilation unit.
4) This is all "compile-time". It has nothing to do with libraries (which are "link time").
Yes, mpi.h will be included multiple times (as will stdlib.h); if mpi.h has include guards similar to foo.h and bar.h, then it won't be an issue.

Resources