Unit test C with compiler specific keywords - c

I am writing unit tests for some embedded C, that run on a host machine (not testing on target yet) and compile with GCC. I have been using the Ceedling build system with the Unity testing framework to test.
One of the files I would like to test includes a file (say a.h) that includes another file (say, cpu.h) that is part of the board support package from the embedded device vendor, and uses keywords specific to the target compiler (e.g. __cregister, such as in extern __cregister volatile unsigned int IER;.
Another issue, again with such a file included from the BSP, is inline assembly asm() sections such as in #define FOO_ASM asm("FOO").
These both of course throws an error when building tests as GCC does not recognise these keywords.
I had thought I could prevent these BSP headers from being added in by having Ceedling generate a mock, by adding #include "mock_a.h" to my test file, but GCC still compiles a.h, and thus b.h.
Is there a best practice way of solving such issues?
I could add something like the below to the BSP file in question, but I am loath to alter vendor code that would change or overwrite my changes with a new version release, I would rather understand how to isolate the unit properly.
// Unknown how __cregister is initially defined
#ifdef TEST
#undef __cregister // Redefine __cregister to nothing
#define __cregister
#endif
extern __cregister volatile unsigned int IER;

It ended up that I followed the method outlined in the link in my comment to the OP.
So for the example from my original post
/* foo.h */
extern __cregister volatile unsigned int IER;
#define FOO_BAR_ASM asm("BAR");
I created the following file, with the same name, within the test/support/ directory and removed the include path for the real BSP files from the test build settings:
/*foo.h - in test/support */
extern volatile unsigned int IER;
#define FOO_BAR_ASM
Then added an include like #include "mock_foo.h" to the test file.

Related

C Project - two libraries use same typedef identifier for different types

I'm working on a project using the MODBUS2 lib, and I want to add the FatFs lib to it to interface with an SD card. Both libraries use identifier SHORT for short and int respectively, and the compiler throws this error:
#258 invalid redeclaration of type name "SHORT"
How can I work around this?
You need to restructure your project in such a way that no translation unit of your library would have to include headers from both libraries (translation unit is a fancy name for a C file).
One approach is to write your own thin "wrapper" functions around MODBUS2 and FatFs functionality. Each wrapper would have to include headers for the library that it wraps, so there would be no compile-time collision. Then the main module of your library would program to your "wrappers", without including MODBUS2 or FatFs headers at all.
Suppose library 1 has
typedef int SHORT;
and library 2 has
typedef short SHORT;
Suppose you have this code:
#include "lib1.h"
#include "lib2.h"
You might be able to fix the compilation error like this:
#define SHORT LIB1_SHORT
#include "lib1.h"
#undef SHORT
#define SHORT LIB2_SHORT
#include "lib2.h"
#undef SHORT
If you do this, you should do it consistently for all #include directives in your code. If you don't have too many #includes, this is not too tedious.
If you don't want to keep these rules in mind all the time, stuff the #define and #undef as first and last thing in all problematic library headers.
The libraries which use those SHORT typedefs without any prefix are ill-designed, since there are no namespaces in C, so they're strongly constraining the users. Ok, but we have to live with that.
If the typedefs were defining the same type, there would be no problem as you can repeat:
typedef int SHORT;
typedef int SHORT;
as many times you want as long as it defines the same base type. But here the types are different, so that's the issue.
One hack would be to use a "word-only" replace on all of the FatFs library includes/sources for instance to replace SHORT by FF_SHORT.
now you can include both libraries without any conflict.
main advantage: no need for more changes or wrappers (like the superior other answer suggests): quick & dirty.
main drawback: must be done at each upgrade of the library interface.

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

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.

C + extern declarations - Where to put them

Alright, I understand how the extern definition works but I don't know what would be the "best" place to put them. Consider the following file structure:
main.c / main.h / global.h
drv_adc.c / drv_adc.h
drv_pwm.c / drv_pwm.h
You might guess, this is quite common for a small microcontroller. The two drivers work on different parts of the hardware and have no interdependencies. Both drivers are able to set a flag (say: adc_irq_occured, pwm_irq_occured) which indicates something has happened and which will be handled in the main.c.
Now I can think of two approaches where I would put the "extern bool adc_irq_occured;" flag.
The drv_adc.h: It somewhat belongs to the ADC driver, therefore I could add it to its header file and instantiate it in the main.c.
I turn the logic around and place the extern declaration into my main.h (or global.h if it has to be so) and instantiate it in my drv_adc.c.
Now the question: Which option is the preferred option here? Is there any good book where I could read about such topics?
In main.c:
int flag = 0;
In main.h:
extern int myGlobal;
In drv_adc.c:
#include "main.h"
In drv_pwm.c:
#include "main.h"
Now that the variable is global , it is less secure , so use it with caution , and make sure any other drv files won't tamper with it.
-- EDIT --
Why not the other way round ?
We put the extern declaration in the header which is to be included by your other files. This is because we declare it once , telling the compiler that only one common version of the flag variable is available to both the drv files , which we included in the header , for more clarity do read this discussion , Difference between putting variables in header vs putting variables in source .

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.

Should I use #include in headers?

Is it necessary to #include some file, if inside a header (*.h), types defined in this file are used?
For instance, if I use GLib and wish to use the gchar basic type in a structure defined in my header, is it necessary to do a #include <glib.h>, knowing that I already have it in my *.c file?
If yes do I also have to put it between the #ifndef and #define or after the #define?
NASA's Goddard Space Flight Center (GSFC) rules for headers in C state that it must be possible to include a header in a source file as the only header, and that code using the facilities provided by that header will then compile.
This means that the header must be self-contained, idempotent and minimal:
self-contained — all necessary types are defined by including relevant headers if need be.
idempotent — compilations don't break even if it is included multiple times.
minimal — it doesn't define anything that is not needed by code that uses the header to access the facilities defined by the header.
The benefit of this rule is that if someone needs to use the header, they do not have to struggle to work out which other headers must also be included — they know that the header provides everything necessary.
The possible downside is that some headers might be included many times; that is why the multiple inclusion header guards are crucial (and why compilers try to avoid reincluding headers whenever possible).
Implementation
This rule means that if the header uses a type — such as 'FILE *' or 'size_t' - then it must ensure that the appropriate other header (<stdio.h> or <stddef.h> for example) should be included. A corollary, often forgotten, is that the header should not include any other header that is not needed by the user of the package in order to use the package. The header should be minimal, in other words.
Further, the GSFC rules provide a simple technique to ensure that this is what happens:
In the source file that defines the functionality, the header must be the first header listed.
Hence, suppose we have a Magic Sort.
magicsort.h
#ifndef MAGICSORT_H_INCLUDED
#define MAGICSORT_H_INCLUDED
#include <stddef.h>
typedef int (*Comparator)(const void *, const void *);
extern void magicsort(void *array, size_t number, size_t size, Comparator cmp);
#endif /* MAGICSORT_H_INCLUDED */
magicsort.c
#include <magicsort.h>
void magicsort(void *array, size_t number, size_t size, Comparator cmp)
{
...body of sort...
}
Note that the header must include some standard header that defines size_t; the smallest standard header that does so is <stddef.h>, though several others also do so (<stdio.h>, <stdlib.h>, <string.h>, possibly a few others).
Also, as mentioned before, if the implementation file needs some other headers, so be it, and it is entirely normal for some extra headers to be necessary. But the implementation file ('magicsort.c') should include them itself, and not rely on its header to include them. The header should only include what users of the software need; not what the implementers need.
Configuration headers
If your code uses a configuration header (GNU Autoconf and the generated 'config.h', for example), you may need to use this in 'magicsort.c':
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "magicsort.h"
...
This is the only time I know of that the module's private header is not the very first header in the implementation file. However, the conditional inclusion of 'config.h' should probably be in 'magicsort.h' itself.
Update 2011-05-01
The URL linked above is no longer functional (404). You can find the C++ standard (582-2003-004) at EverySpec.com; the C standard (582-2000-005) seems to be missing in action.
The guidelines from the C standard were:
§2.1 UNITS
(1) Code shall be structured as units, or as stand-alone header files.
(2) A unit shall consist of a single header file (.h) and one or more body (.c) files. Collectively the header and body files are referred to as the source files.
(3) A unit header file shall contain all pertinent information required by a client unit. A unit’s
client needs to access only the header file in order to use the unit.
(4) The unit header file shall contain #include statements for all other headers required by the unit header. This lets clients use a unit by including a single header file.
(5) The unit body file shall contain an #include statement for the unit header, before all other #include statements. This lets the compiler verify that all required #include statements are in
the header file.
(6) A body file shall contain only functions associated with one unit. One body file may not
provide implementations for functions declared in different headers.
(7) All client units that use any part of a given unit U shall include the header file for unit U; this
ensures that there is only one place where the entities in unit U are defined. Client units may
call only the functions defined in the unit header; they may not call functions defined in the
body but not declared in the header. Client units may not access variables declared in the body
but not in the header.
A component contains one or more units. For example, a math library is a component that contains
multiple units such as vector, matrix, and quaternion.
Stand-alone header files do not have associated bodies; for example, a common types header does
not declare functions, so it needs no body.
Some reasons for having multiple body files for a unit:
Part of the body code is hardware or operating system dependent, but the rest is common.
The files are too large.
The unit is a common utility package, and some projects will only use a few of the
functions. Putting each function in a separate file allows the linker to exclude the ones not
used from the final image.
§2.1.1 Header include rationale
This standard requires a unit’s header to contain #include statements for all other headers required
by the unit header. Placing #include for the unit header first in the unit body allows the compiler to
verify that the header contains all required #include statements.
An alternate design, not permitted by this standard, allows no #include statements in headers; all
#includes are done in the body files. Unit header files then must contain #ifdef statements that check
that the required headers are included in the proper order.
One advantage of the alternate design is that the #include list in the body file is exactly the
dependency list needed in a makefile, and this list is checked by the compiler. With the standard
design, a tool must be used to generate the dependency list. However, all of the branch
recommended development environments provide such a tool.
A major disadvantage of the alternate design is that if a unit’s required header list changes, each file
that uses that unit must be edited to update the #include statement list. Also, the required header list
for a compiler library unit may be different on different targets.
Another disadvantage of the alternate design is that compiler library header files, and other third party
files, must be modified to add the required #ifdef statements.
A different common practice is to include all system header files before any project header files, in
body files. This standard does not follow this practice, because some project header files may
depend on system header files, either because they use the definitions in the system header, or
because they want to override a system definition. Such project header files should contain #include
statements for the system headers; if the body includes them first, the compiler does not check this.
GSFC Standard available via Internet Archive 2012-12-10
Information courtesy Eric S. Bullington:
The referenced NASA C coding standard can be accessed and downloaded via the Internet archive:
http://web.archive.org/web/20090412090730/http://software.gsfc.nasa.gov/assetsbytype.cfm?TypeAsset=Standard
Sequencing
The question also asks:
If yes, do I also have to put it (the #include lines) between the #ifndef and #define or after the #define.
The answer shows the correct mechanism — the nested includes, etc, should be after the #define (and the #define should be the second non-comment line in the header) — but it doesn't explain why that's correct.
Consider what happens if you place the #include between the #ifndef and #define. Suppose the other header itself includes various headers, perhaps even #include "magicsort.h" indirectly. If the second inclusion of magicsort.h occurs before #define MAGICSORT_H_INCLUDED, then the header will be included a second time before the types it defines are defined. So, in C89 and C99, any typedef type name will be erroneously redefined (C2011 allows them to be redefined to the same type), and you will get the overhead of processing the file multiple times, defeating the purpose of the header guard in the first place. This is also why the #define is the second line and is not written just before the #endif. The formula given is reliable:
#ifndef HEADERGUARDMACRO
#define HEADERGUARDMACRO
...original content of header — other #include lines, etc...
#endif /* HEADERGUARDMACRO */
A good practice is to only put #includes in an include file if the include file needs them. If the definitions in a given include file are only used in the .c file then include it only in the .c file.
In your case, i would include it in the include file between the #ifdef/#endif.
This will minimize dependencies so that files that don't need a given include won't have to be recompiled if the include file changes.
Usually, library developers protect their includes from multiple including with the #ifndef /#define / #endif "trick" so you don't have to do it.
Of course, you should check... but anyways the compiler will tell you at some point ;-) It is anyhow a good practice to check for multiple inclusions since it slows down the compilation cycle.
During compilation preprocessor just replaces #include directive by specified file content.
To prevent endless loop it should use
#ifndef SOMEIDENTIFIER
#define SOMEIDENTIFIER
....header file body........
#endif
If some header was included into another header which was included to your file
than it is not necessary to explicitly include it again, because it will be included into the file recursively
Yes it is necessary or the compiler will complain when it tries to compile code that it is not "aware" of. Think of #include's are a hint/nudge/elbow to the compiler to tell it to pick up the declarations, structures etc in order for a successful compile. The #ifdef/#endif header trick as pointed out by jldupont, is to speed up compilation of code.
It is used in instances where you have a C++ compiler and compiling plain C code as shown here
Here is an example of the trick:
#ifndef __MY_HEADER_H__
#define __MY_HEADER_H__
#ifdef __cplusplus
extern "C" {
#endif
/* C code here such as structures, declarations etc. */
#ifdef __cplusplus
}
#endif
#endif /* __MY_HEADER_H__ */
Now, if this was included multiple times, the compiler will only include it once since the symbol __MY_HEADER_H__ is defined once, which speeds up compilation times.
Notice the symbol cplusplus in the above example, that is the normal standard way of coping with C++ compiling if you have a C code lying around.
I have included the above to show this (despite not really relevant to the poster's original question).
Hope this helps,
Best regards,
Tom.
PS: Sorry for letting anyone downvote this as I thought it would be useful tidbit for newcomers to C/C++. Leave a comment/criticisms etc as they are most welcome.
You need to include the header from your header, and there's no need to include it in the .c. Includes should go after the #define so they are not unnecessarily included multiple times. For example:
/* myHeader.h */
#ifndef MY_HEADER_H
#define MY_HEADER_H
#include <glib.h>
struct S
{
gchar c;
};
#endif /* MY_HEADER_H */
and
/* myCode.c */
#include "myHeader.h"
void myFunction()
{
struct S s;
/* really exciting code goes here */
}
I use the following construct to be sure, that the needed include file is included before this include. I include all header files in source files only.
#ifndef INCLUDE_FILE_H
#error "#include INCLUDE.h" must appear in source files before "#include THISFILE.h"
#endif
What I normally do is make a single include file that includes all necessary dependencies in the right order. So I might have:
#ifndef _PROJECT_H_
#define _PROJECT_H_
#include <someDependency.h>
#include "my_project_types.h"
#include "my_project_implementation_prototypes.h"
#endif
All in project.h. Now project.h can be included anywhere with no order requirements but I still have the luxury of having my dependencies, types, and API function prototypes in different headers.
Just include all external headers in one common header file in your project, e.g. global.h and include it in all your c files:
It can look like this:
#ifndef GLOBAL_GUARD
#define GLOBAL_GUARD
#include <glib.h>
/*...*/
typedef int YOUR_INT_TYPE;
typedef char YOUR_CHAR_TYPE;
/*...*/
#endif
This file uses include guard to avoid multiple inclusions, illegal multiple definitions, etc.

Resources