#include guards does not work and #pragma once is obsolete - c

There are two head files _stub_defs.h
///stub code
#pragma once
#include "random.h"
#include <stdarg.h>
and stasrg.h
#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
typedef __builtin_va_list __gnuc_va_list;
#endif
When I use my cross-compiler(sparc-rtems-gcc) to compile, the two head files both are included.Then the terminal tells me:
warning: #pragma once is obsolete
stdarg.h: conflicting types for `__gnuc_va_list'
stdarg.h: previous declaration of `__gnuc_va_list'
Obviously, #include guards does not work.Is this the problem of head files' codes or the problem of my cross-compiler?

The include guards work. You have another problem.
The best way to debug this is to run only the C preprocessor. For gcc (including cross compiler gcc), you can use the -E option. Just add this to your compile stage. Instead of getting an object file, you will get a C file after the preprocessor stage.
Take that file, and search for the duplicate definition there. The file will also have markers that tell the compiler which file this definition originally came from, as well as markers when includes are nested. If you follow those, you will see both where the two definitions come from and which file included each of them.

Related

Typedef is declared in other header, is included in necessary files, however produced: Error[Pe020]: identifier "" is undefined. Why?

Let's say I have the project in C in IAR, and I'm working with these 4 files. I have a header for defines, and another header for extern functions. I also have two .c files, one for main, and one for functions, as shown below.
First header file: header1.h
#ifndef __HEADER1_H
#define __HEADER1_H
#include "header2.h"
#include "otherheader.h"
// bunch of 'define' here
typedef uint8_t macAddr[8];
#endif
Another header file: header2.h
#ifndef __HEADER2_H
#define __HEADER2_H
//other extern functions here
extern void getMAC(macAddr deviceAddr);
#endif
main.c file here:
#include "header1.h"
void main ()
{
macAddr dev1Address = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
getMAC(dev1Address);
}
function.c file here:
#include "header1.h"
void getMAC(macAddr deviceAddr)
{
uint8_t transmit[8];
for (int i = 0; i<8; i++)
transmit[i] = deviceAddr[i];
}
The error reported is this:
Error[Pe020]: identifier "macAddr" is undefined
I'm having a little trouble understanding why this does not work. The first header (where macAddr is defined) includes the second header (where getMac() function is declared), and the first header is included in main.c as well as function.c. As far as I understand, there is no circular includes (as other questions suggested... correct me if I'm wrong, and show me how)
Problem is that header1.h includes header2.h, but header2.h requires macAddr which is not yet defined.
Rule of thumb is that each file should include only the files it needs. Thus:
header1.h has a single typedef. It should only include stdint.h.
header2.h needs macAddr to work, thus it should include header1.h.
main.c uses getMAC, so it should include header2.h. header1.h is already included, so no need to include it.
function.c strictly only needs header1.h, but it's good practice to make sure that function declaration and definition match, so it should include header2.h instead.
It seems like header1.h is used as a monolith header that is used to include everything (It's hard to be sure because your example has so few files). This is a very bad practice. It can increase compilation times, and makes refactoring hard since dependencies are difficult to track.
Ideally each header should only have single well defined responsibility. It's not always possible, but it's a good goal.
Circular includes are not a huge issue as long as you use header guards as you have, and not include everything everywhere unless it's needed. Sometimes you might need to add extra forward declarations, but that's about it.
Here's some additional notes:
As user3629249 and others noted, you really shouldn't declare symbols starting with _ underscore. These are reserved for C standard or compiler use.
I don't recommend using typedef on arrays (or pointers). Arrays decay to pointer in some cases without telling you, so when using typedef this is hidden from user and can cause bugs with careless use. I would wrap it struct instead:
typedef struct { uint8_t address[8]; } MAC_T;

What is the conventional way of defining macros in main.c that are needed in other header files?

For example I have a can.h header file that contains
#ifdef MC
extern int speed;
// many more variables and function prototypes
#endif
EDIT: I would want an option for the user to define MC that enables such variable and function prototypes. It is to be defined in C main alongside include directives (e.g. #define MC) however, other header files cannot link to main.c. Instead, i ended up defining such macros in can.h header itself. All i can think is writing a main.h too where can.h will include main.h. are there other ways to go around this problem?
It's not entirely clear to me what you are trying to do, but perhaps you want this:
/* in file can.h */
extern int speed;
and then
/* in file main.c */
#include "can.h"
int speed;
The header can.h just declares the existence of speed so that other modules can refer to it as an external symbol. The storage for this object is then allocated in main.c, when you write the the definition of speed.
You can either create a configuration header that has all the macros that you want defined and #include it in every header, or you can define configuration macros on the command line.
Use #include - Then you get those bits that you require
Inclusion is simply file content insertion by the preprocessor, anything declared or defined prior to inclusion will be defined in the include file. So:
#define MC
#include "can.h"
While that achieves what you have asked, I would not necessarily recommend it however, and might question the design.
You can have such macro added at your project level.
Such macro are also known as Preprocessor definitions. Visual studio provides such definition in project settings/configurations..
So you can have it added there and compile the solution for including mentioned declarations or remove it if you don't want to include it.
Adding the screen shot.

How to understand a #include inside a enum definition?

How do I interpret this C code:
typedef enum {
#include <test.h>
enum1,
enum2,
…
} test_enum;
test.h includes many macros. How to understand this?
Does means that the definitions of the enum needs the macros defined inside the header file?
Can #include appear anywhere?
An #include statement may appear on any line. It is most often used to include entire declarations. However, it can be used to insert any text.
It may be that test.h contains a list of names to be declared inside the enum. It may also contain preprocessor statements, such as macro definitions or #if … #endif statements.
You would have to show the contents of test.h for further help understanding it.
#include and #define are pre processor directives not actual code.
You can put them anywhere (except as part of a literal string) - some compilers are more fussy than others (i.e. the # has to be in column 0).
The Preprocessor expands these out as required, and that is what the compiler sees. As to what it means in your case, depends on the content of test.h
There is normally a compiler option to see your code with all the preprocessor stuff expanded (used to be -e or -E on gcc I think)
The #include directive causes the contents of the included file to be placed exactly at the point of the #include directive. The resulting code is what it is once that expansion has taken place, and can be any valid language construct.
If the included file contains:
enum_a,
enum_b,
enum_c,
Then after inclusion, your code would look like:
typedef enum {
enum_a,
enum_b,
enum_c,
enum1,
enum2,
…
} test_enum;
Which is a valid construct.
A #include directive can appear anywhere. See this.
Pre-processor statements can occur anywhere and are simple textual substitutions. Whether or not the processed code is valid C code is checked by the compiler, not the pre-processor.
Depending on your compiler you can review the changes done by the pre-processor.
For gcc, this would be the -E flag, so by compiling your source code with
gcc -E in.c
you can see which changes code is contained in the enum declaration after inserting test.h and
processing it.

Putting C Code in another File

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.

Includes within header files

Should header files have #includes?
I'm generally of the opinion that this kind of hierarchical include is bad. Say you have this:
foo.h:
#include <stdio.h> // we use something from this library here
struct foo { ... } foo;
main.c
#include "foo.h"
/* use foo for something */
printf(...)
The day main.c's implementation changes, and you no longer use foo.h, the compilation will break and you must add <stdio.h> by hand.
Versus having this:
foo.h
// Warning! we depend on stdio.h
struct foo {...
main.c
#include <stdio.h> //required for foo.h, also for other stuff
#include "foo.h"
And when you stop using foo, removing it breaks nothing, but removing stdio.h will break foo.h.
Should #includes be banned from .h files?
You've outlined the two main philosophies on this subject.
My own opinion (and I think that's all that one can really have on this) is that headers should as self-contained as possible. I don't want to have to know all the dependencies of foo.h just to be able to use that header. I also despise having to include headers in a particular order.
However, the developer of foo.h should also take responsibility for making it as dependency-free as possible. For example, the foo.h header should be written to be free of a dependency on stdio.h if that's at all possible (using forward declarations can help with that).
Note that the C standard forbids a standard header from including another standard header, but the C++ standard doesn't. So you can see the problem you describe when moving from one C++ compiler version to another. For example, in MSVC, including <vector> used to bring in <iterator>, but that no longer occurs in MSVC 2010, so code that compiled before might not any more becuase you may need to specifically include <iterator>.
However, even though the C standard might seem to advocate the second philosophy, note that it also mandates that no header depend on another and that you can include headers in any order. So you get the best of both worlds, but at a cost of complexity to the implementers of the C library. They have to jump through some hoops to do this (particularly to support definitions that can be brought in through any of several headers, like NULL or size_t). I guess that the people who drafted the C++ standard decided adding that complexity to impersonators was no longer reasonable (I don't know to what degree C++ library implementors take advantage of the 'loophole' - it looks like MS might be tightening this up, even if it's not technically required).
My general recommendations are:
A file should #include what it needs.
It should not expect something else to #include something it needs.
It should not #include something it doesn't need because something else might want it.
The real test is this: you should be able to compile a source file consisting of any single #include and get no errors or warnings beyond "There is no main()". If you pass this test, then you can expect anything else to be able to #include your file with no problems. I've written a short script called "hcheck" which I use to test this:
#!/usr/bin/env bash
# hcheck: Check header file syntax (works on source files, too...)
if [ $# -eq 0 ]; then
echo "Usage: $0 <filename>"
exit 1
fi
for f in "$#" ; do
case $f in
*.c | *.cpp | *.cc | *.h | *.hh | *.hpp )
echo "#include \"$f\"" > hcheck.cc
printf "\n\033[4mChecking $f\033[0m\n"
make -s $hcheck.o
rm -f hcheck.o hcheck.cc
;;
esac
done
I'm sure there are several things that this script could do better, but it should be a good starting point.
If this is too much, and if your header files almost always have corresponding source files, then another technique is to require that the associated header be the first #include in the source file. For example:
Foo.h:
#ifndef Foo_h
#define Foo_h
/* #includes that Foo.h needs go here. */
/* Other header declarations here */
#endif
Foo.c:
#include "Foo.h"
/* other #includes that Foo.c needs go here. */
/* source code here */
This also shows the "include guards" in Foo.h that others mentioned.
By putting #include "Foo.h" first, Foo.h must #include its dependencies, otherwise you'll get a compile error.
Well, main shouldn't rely on "foo.h" in the first place for stdio. There's no harm in including something twice.
Also, perhaps foo.h doesn't really need stdio. What's more likely is that foo.c (the implementation) needs stdio.
Long story short, I think everyone should just include whatever they need and rely on include guards.
Once you get into projects with hundreds or thousands of header files, this gets untenable. Say I have a header file called "MyCoolFunction.h" that contains the prototype for MyCoolFunction(), and that function takes pointers to structs as parameters. I should be able to assume that including MyCoolFunction.h will include everything that's necessary and allow me to use that function without looking in the .h file to see what else I need to include.
If the header file needs a specific header, add it to the header file
#ifndef HEADER_GUARD_YOUR_STYLE
#define HEADER_GUARD_YOUR_STYLE
#include <stdio.h> /* FILE */
int foo(FILE *);
#endif /* HEADER GUARD */
if the code file doesn't need a header, don't add it
/* #include <stdio.h> */ /* removed because unneeded */
#include <stddef.h> /* NULL */
#include "header.h"
int main(void) {
foo(NULL);
return 0;
}
Why don't you #include stuff in the *.c file corresponding to the header?

Resources