I'm writing a program in C intended to be compiled and run on a HP NonStop machine. However, I want to do the main development on my workstation running Linux. The HP NonStop C-Compiler requires non-standard #include directives like the following:
#include <stdio.h> nolist
For each #include directive, my workstation's GCC is complaining:
S88USF.c:139:21: warning: extra tokens at end of #include directive
How can I suppress this particular warning?
Note: On SO, similar questions have already been asked, the correct answer being along the lines of "don't give gcc any reason to complain in the first place". In this scenario however, I explicitly want to have the #include directives exactly as they are.
I know what I'm doing, I just don't know how to inform gcc about it.
One workaround would be to define a header that includes the following preproccesor macro:
//hp_workaround.h
#ifdef HP_
#define HP_INCLUDE_DIRECTIVE(x) x
#else
#define HP_INCLUDE_DIRECTIVE(x)
#endif
then guard your directives with this macro
#include "hp_workaround.h"
#include <stdio.h> HP_INCLUDE_DIRECTIVE(nolist)
Macroexpansion happening within include can probably help.
GCC will accept this:
#define nolist
#include <stdlib.h> nolist
/* maybe #undef nolist here */
Related
I'm writing the header of a kernel module. The header is known to the module, but also used by callers in user space. This is a problem, because some types used should be included from different files depending on whether the header is currently in user or kernel space (or so this question makes me think).
I don't want to maintain two separate header files, so I've been thinking of a solution like this:
#ifndef IN_KERNEL
#include <stdint.h>
#else
#include <linux/types.h>
With IN_KERNEL being defined somewhere in my kernel code. Is there a preprocessor constant that already does this?
From reading this, it seems that an existing constant used for this purpose is __KERNEL__.
#ifndef __KERNEL__
#include <stdint.h>
#else
#include <linux/types.h>
#endif
I was studying the code for the Kilo text editor here:
https://github.com/antirez/kilo/blob/master/kilo.c
And I noticed that the includes defined stdlib.h twice (UPDATE: Comments are mine):
#include <termios.h>
#include <stdlib.h> // first time
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h> // second time
#include <ctype.h>
Is this merely an error? Or is there something to it? I ask because the author of the code doesn't seem like someone who makes a lot of mistakes. I wouldn't want to suggest a change in ignorance.
As stdlib.h has an include guard, there is no point in including it twice. Probably the mistake was caused by merging two files, both dependant on stdlib.h.
There is no harm in including a standard header more than once, although it is totally unnecessary.
The C standard says the following about this:
Standard headers may be included in any order; each may be included
more than once in a given scope, with no effect different from being
included only once, except that the effect of including <assert.h>
depends on the definition of NDEBUG.
There's no reason to include a particular header file twice. If the file has proper include guards, the second inclusion will have no effect. If it does not have include guards, you'll likely get a slew of errors for multiple definitions for typedefs, among others.
In the case of system headers, they almost always have include guards. The contents of stdlib.h might look something like this:
#ifndef _STDLIB_H
#define _STDLIB_H 1
...
// type definitions, #defines, declarations, etc.
...
#endif /* stdlib.h */
The first time stdlib.h is included, the #ifndef will evaluate to true, _STDLIB_H is defined, and the remaining contents are inserted into the file being compiled. The second time stdlib.h is included, the #ifndef will evaluate to false since _STDLIB_H is defined and the contents of the file between the #ifndef and #endif will not be inserted again.
Most UNIX/Linux systems do this. In contrast, Microsoft is known for not managing its OS specific include files properly. If you included them in the wrong order you'll end up with lots of errors.
The only scenario it can make a difference is when one of the includes is undefining some symbols (including the include guards) from the previous includes. Consider 2 files:
1.h:
#define A 1
2.h:
#undef A
Now, the following sequence:
#include "1.h"
#include "2.h"
int B = A;
will produce an error, as A is undefined.
The following sequence will be just fine:
#include "1.h"
#include "2.h"
#include "1.h"
int B = A;
Now, if 1.h has the include guards:
1.h:
#ifndef GUARD_1
#define GUARD_1
#define A 1
#endif
The 2.h can do:
#undef GUARD_1
#undef A
and cause the same effect.
Now to stdlib.h. You can compose something like this in your x.h header:
#undef _STDLIB_H // Kill the include guard of stdlib.h
#undef NULL // Undefine some important symbol from stdlib.h
Now, this sequence:
#include <stdlib.h>
#include "x.h"
will have NULL undefined
And this:
#include <stdlib.h>
#include "x.h"
#include <stdlib.h>
will have it defined.
Though not directly applicable to <stdlib.h>, a reason for including a user-defined header file twice: Testing if including the header file twice incurs a problem.
Example: Consider a pair of files foo.h and foo.c declaring and implementing a bunch of foo_ functions, defines, types, etc.
File foo.c
#include "foo.h"
#include "foo.h"
rest of foo.c code ...
A 2nd calling of an include file should not cause a problem and foo.c tests that.
OTOH, foo.c did not test if including a header file only once is OK.
I working in C with vfork(). My program working fine, but I have warning about implicit declaration.
My code:
if(vfork()==0){
...
}
My warning is:
implicit declaration of function 'vfork' [-Wimplicit-function-declaration] if(vfork()==0){^
I include those:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
If I use fork() and not vfork() warning gone. Soo problem is only vfork() in my program.
I don't know what this mean or how I fix that.
You need to include these 2 headers:
#include <sys/types.h>
#include <unistd.h>
Also, add this line in the beginning of the program:
#define _BSD_SOURCE
If you already have the required include files, then, depending on your system version, you may need to define some feature test macros. Please see documentation for your system (man vfork on unix-like systems)
Adding onto Igor's answer, make sure you aren't compiling for C99. clang gives me the error "implicit declaration of function 'vfork' is invalid in C99", and removing -std=c99 from the arguments fixed the issue.
I am programming an AVR microcontroller, and in the programmers notepad in the WINAVR Suite.
I am trying to seperate my code, however the sepeaet .c file I am unable to use AVR pre-defined variables. (the variables AVR supplies to point to certain BITs)
for example,
this code will work in my main.c file. but not in another random.c file:
UBRR0H = (unsigned char)(ubrr>>8);
it gives the error :
random.c:6: error: 'UBRR0H' undeclared (first use in this function)
in my main.c file it only has the following includes:
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include <string.h>
#include <avr/interrupt.h>
#include "lcd.h"
#include "random.h"
You have to include avr/io.h in your projet and also specify the mcu in the gcc compiler command line with -mmcu= option.
You have to create file like yours.h, where you put or your function definitions and macros definitions:
#define UBRR0H (unsigned char)(ubrr>>8);
int mine_function( char, char, int);
...
extern int global_variable;
not sure whether UBRR0H is macro or extranal variable
In addition use something about extern variables and some articles about how to use them.
And than in every your .c file you should:
#include "yours.h"
If you get in troubles because you'll end up with many .h files and you'll be including the same thing multiple times (will cause error, previously defined there), there easy hack, in yours.h:
#ifndef _H_YOURS_INCLUDED_
#define _H_YOURS_INCLUDED_ 1
// Your real content
#endif /* _H_YOURS_INCLUDED_ */
If you're using "library" definitions in any compilation unit (.c file), you'll need to include the right headers in that unit (file). I'm guessing you're missing #include or such in the random.c file. Having it just in main.c won't help the compiler while its compiling random.c. :)
(The linker is a different matter.)
One way to find out where a definition is is to simply grep the compiler and libc source (include) directories and look for the name. That won't necessarily tell you what you're meant to do to get it. I suspect that that one is a chip-specific register name that appears in the include file for your specific chip and gets loaded while going through io.h depending on the compiler switches.
If it goes missing while using a different chip, check the datasheet to make sure the register/peripheral exists in your particular chip and check the include files for the exact spelling. There may be differences.
I'm trying to compile a C program but I get the error 'RTLD_NEXT' undeclared. I think this is supposed to be defined in dlfcn.h which the c program includes, but when I looked inside dlfcn.h there is no RTLD_NEXT.
How do I fix this?
The issue here is that RTLD_NEXT is not defined by the posix standard . So the GNU people don't enable it unless you #define _GNU_SOURCE or -D_GNU_SOURCE.
Other relevant pieces of POSIX are dlfcn.h and dlsym.h. Interestingly, the later mentions RTLD_NEXT. Apparently, the GNU people are a bit confused about what is an extension and what is not.
According to man dlsym it is #define _GNU_SOURCE (just one leading underscore) before the dlfcn.h is included. (RHEL6.1).
Try #define __GNU_SOURCE as first line in your sources.
There must be one underscore. #define _GNU_SOURCE
Further, this must be your first preprocessor directive.For example:
#define _GNU_SOURCE
#include <stdio.h>