why put the code in an header - c

Normaly if I make a small code snipet, I usually put it in a whathever.c - file. From the C-file I include a .h -file with other includes or some global varaibles.
I've just heard that the compiler makes the code in a header faster, or somtehing I would love if someone could explain or comment this.
Example code in a header instead of a c-file (could be in a c) ->
#define PWM_INTERRUPT \
void InterruptHook(void) \
{ \
PR4 ^= _SoftPWM_Toggle; \
\
PIR3bits.TMR4IF = 0; \
\
_asm \
INCF PR4,0,ACCESS \
CPFSLT TMR4,ACCESS \
_endasm \
\
/* if(TMR4 > PR4) */ \
PIR3bits.TMR4IF = 1; \
\
SOFT_PWM_PIN ^= 1; \
\
_asm \
RETFIE 1 \
_endasm \
}

You can't put a macro in a separate .c file, because macros are handled by the preprocessor, which is the first step in the compilation process, and separate .c files are handled in the link stage, which is the last step.
Using a macro instead of a function might be faster, because it avoids the overhead of a function call. However, it will slow your compiles down because it compiles the same code multiple times. It will make your code larger because of redundant copies. If caching is an issue, it might actually run slower because of repeatedly fetching different redundant copies into cache. There's no way to know for sure without profiling.
If you're talking about the difference between putting a macro in the same .c file and a header file, there's no difference performance-wise. You just would have to copy and paste it into every .c file that uses it.

The "rumor" you heard relates to the way some compilers (most notable C++) tend to inline code that it is placed in a .h file.
This link (Michael Barr's) provides some very good tips on what belongs (and doesn't belong) in a C header file.

Before anything in your .c/.cpp file is compiled the preprocessors replaces all of the #include directives with the content of the given *.h file => This end up in a single file for the compiler => No difference in performance between source and header files.

In your example, the macro was defined in a header file in order to be used in multiple compilation units (c files) - I doubt it has anything to do with speed.

Acctually, another answer is: When declaring the high priority interrupt within a macro, the code within the macro is the only one going there, thous doing the interrupt handler fast.
When I define the interrupt outside the macro as a ordinary function, I noticed a lot of code put in the interrupt rutine by the compiler, code I could'nt see whitout using Disassambly Listing in MPLAB IDE.
The later slowing down my rutine fron 16 cycles to 168.

Related

Is it possible to define macro inside macro?

I want to use macro parameter like this:
#define D(cond,...) do{ \
#if cond \
#define YYY 1 \
#else \
#define YYY 0 \
} while(0)
Is it possible?
UPD
Maybe when sources will be preprocessed twice: gcc -E source.c | gcc -xc - next will work:
#define D(cond,...) #define YYY cond&DEBUG
#if YYY
#define D(...) printf( __VA_ARGS__ )
#else
#define D(...)
#endif
No, because C 2011 [N1570] 6.10.3.4 3 says, about macro replacement, “The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one,…”
This is not possible. Read about the GNU cpp preprocessor and the C11 standard (i.e. n1570), and check here. The C preprocessor is (conceptually at least) run before the rest of the compiler (which gets the preprocessed form of your translation unit). BTW, for a file foo.c you could use gcc -C -E foo.c > foo.i (using GCC) to get inside foo.i its preprocessed form, and you can inspect that foo.i -since it is a textual file- with a pager or an editor.
However, a .c file can be generated (generating C code is a common practice, at least since the 1980s; for example with yacc, bison, rpcgen, swig, ....; many large software projects use specialized generators of C or C++ code...). You might consider using some other tool, perhaps the GPP preprocessor (or GNU m4) or some other program or script, to generate your C file (from something else). Look also into autoconf (it might have goals similar to yours).
You may want to configure your build automation tool for such purpose, e.g. edit your Makefile for GNU make.
No, this is not possible.
During translation, all preprocessing directives (#define, #include, etc.) are executed before any macro expansion occurs, so if a macro expands into a preprocessing directive, it won't be interpreted as such - it will be interpreted as (invalid) source code.
As pointed out by others this is not possible but there is a work around:
int YYY;
/* global scope variables are sometimes considered bad practice... */
#define D(cond,...) do{ \
if (cond) { \
YYY = 1; \
} \
else { \
YYY = 0; \
} \
} while(0)
Use an optimizing flag (ex: gcc/clang -O3) and it will replace the dead code as if it was a macro. Obviously you may want to change the type of YYY but you seem to use it like a boolean.
No, you cannot. The C preprocessor cannot know what is going to occur during runtime.
The preprocessor goes through the program before it is even compiled and replaces every macro defined with its assigned value.
This is some poor man's code generation, for when integrating another tool to the project is overkill.
Define a macro like this, expanding for your needs:
#define NESTED /* Comment out instead of backslash new lines.
*/ /*
*/ UNDEF REPLACED /*
*/ /*
*/ IFDEF CONDITION /*
*/ DEFINE REPLACED 1 /*
*/ ELSE /*
*/ DEFINE REPLACED 0 /*
*/ ENDIF
Your version of NESTED can be a function-like macro, and REPLACED can have a more elaborated body.
Leave CONDITION and the directive named macros without a definition.
DEFINE CONDITION to control which value NESTED gets on compilation, similarly to normal #ifdef usage:
DEFINE CONDITION
NESTED
int i = REPLACED; //i == 1
UNDEF CONDITION
NESTED
int z = REPLACED; //z == 0
Source code that uses NESTED and the other macros will not compile. To generate a .c or .cpp file that you can compile with your chosen options, do this:
gcc -E -CC source.c -o temporary.c
gcc -E \
-DDEFINE=\#define -DUNDEF=\#undef \
-DIFDEF=\#ifdef -DELSE=\#else -DENDIF=\#endif \
temporary.c -o usableFile.c
rm temporary.c #remove the temporary file
-E means preprocess only, not compile. The first gcc command expands NESTED and all normally defined macros from the source. As DEFINE, IFDEF, etc. are not defined, they and their future arguments remain as literal text in the temporary.c file.
-CC makes the comments be preserved in the output file. After the preprocessor replaces NESTED by its body, temporary.c contains the directive macros in separate lines, with the comments. When the comments are removed on the next gcc command, the line breaks remain by the standard.
# is accepted in the body of a macro that takes no arguments. However, unlike macros, directives are not rescaned and executed on expansion, so you need another preprocessor pass to make nested defines work. All preprocessing related to the delayed defines needs to be delayed too, and made available to the preprocessor at once. Otherwise, directives and arguments needed in a later pass are consumed and removed from the code in a previous one.
The second gcc command replaces the -D macros by the delayed directives, making all of them available to the preprocessor starting on the next pass. The directives and their arguments are not rescaned in the same gcc command, and remain as literal text in usableFile.c.
When you compile usableFile.c, the preprocessor executes the delayed directives.

How to mock functions in headerfiles?

What I am doing:
I am using cmocka to run unit tests for large embedded project.
The embedded project is compiled with a arm-gcc-compiler.
The unit tests are compiled with the normal gcc using fragments of the embedded code and the cmocka library.
Normally cmocka recommends to use the -Wl,--wrap=functionName flag to mock (replace) some unneeded sub-functions. This works pretty good.
The Problem:
Well, within my embedded code there is one header file (foo.h), which contains some functions (declared as inline). One of these functions contains some assembler code for the arm-gcc-compiler, which, of course, cannot be compiled by the gcc.
Stupidly the wrap-flag seems not to work on functions which are placed in header files.
Question:
How to mock this function in the headerfile away?
How I tried to solve the Problem:
I thought about inserting some #idef macros to exclude the mentioned assembler section. But this cannot be done because this file belongs to a licensed library and I am not allowed to change its content.
I could extract my function-under-test into an additional files so that foo.h doesn't need to be included anymore. But this would confuse the embedded source codes structure.
Exact lines of problem
The exact code is placed in portmacro.h of freeRtos at line 233:
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI;
__asm volatile
(
" mov %0, %1 \n" \
" msr basepri, %0 \n" \
" isb \n" \
" dsb \n" \
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
);
}
where as portFORCE_INLINE is defined as:
#define portFORCE_INLINE inline __attribute__(( always_inline))
Stupidly the wrap-flag seems not to work on functions
which are placed in header files.
It's not the fault of wrap, the function has been inlined by compiler so there's nothing linker can do.
How to mock this function in the headerfile away?
One option is to use sed to automatically patch the offending code before passing it to gcc. E.g. to change
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI;
...
}
portFORCE_INLINE static void vPortRaiseBASEPRI_2( void )
{
uint32_t ulNewBASEPRI;
...
}
from your example to
portFORCE_INLINE static void vPortRaiseBASEPRI( void );
portFORCE_INLINE static void vPortRaiseBASEPRI_2( void );
do
cat tmp.c | sed '/inline\|INLINE/,/^}$/{ s/^\(.*\(inline\|INLINE\).*\)/\1;/; /inline\|INLINE/!d }'
The regex is quite sloppy, it relies on the fact that all definitions in header will have the INLINE marker but should probably be enough in your case.
You can embed above command into your Makefile to generate custom header in a temp folder and then override default header with -Ipath/to/temp/folder flag.
I've not used cmocka so I'm unsure if there is a method for managing this already within the framework.
However, cmock uses a method whereby the header is copied to a location somewhere higher in the include hierarchy of the test build (and only the test build, the location is not included even implicitly by the release build).
The copy of this header then can be edited such that the function declaration simply becomes port void vPortRaiseBASEPRI( void );. Then when the mocks are generated a mock is generated for this (and the other function declarations within the same header) just like in any other case. Because hte mocks are being generated it does not matter that there is no matching source code definition (i.e. .c file) for the function(s).
See the "Dealing with compiler-specific stuff" section at https://dmitryfrank.com/articles/unit_testing_embedded_c_applications
And my similar question and how I solved it here: Unit test C with compiler specific keywords

What is the purpose of "__SRCVERSION" function at the end of each C file?

I am working on the source code of a Unix-based kernel. I noticed that the last line of each source code file (.c or .h) is a specific line with the following format:
__SRCVERSION( "$URL: ... $ $Rev: 219996 $" )
The URL points to the web address of the same file. I'm wondering what does that mean, and what is it actually for? Would it be any problem if I delete this line from all of my source code files?
Macros like this are often used to embed versioning information into binaries when they are compiled. They can be updated automatically when fetched out of a source control system with appropriate rules. Removing them shouldn't cause any harm, but you will lose the benefit of being able to search a binary to identify which versions of your source files were used to compile it.
As #Keith Thompson says below, it may also be possible to configure your build to not embed the information. Below is an example of the macro definition taken from here (different systems are likely to have different definitions). You can see that it uses the __USESRCVERSION definition to decide which version of the __SRCVERSION macro is used:
#ifndef __USESRCVERSION
#define __SRCVERSION(id)
#else /* __USESRCVERSION */
#ifdef __QNXNTO__
#if defined __SRCVERSION
#undef __SRCVERSION
#endif /*__SRCVERSION */
#define __SRCVERSION(id) \
__asm__(".section .ident,\"SM\",#progbits,1"); \
__asm__(".asciz " #id); \
__asm__(".previous");
#endif /* __QNXNTO__ */
#endif /* __USESRCVERSION */

Include a header file for parsing of all other files with Doxygen preprocessor

I want to include the #defines from a h file for parsing of all other files with Doxygen.
Project background:
My C project includes a header file config.h on it's the build command.
It also defines a target MODEL_A on the same build command.
config.h creates defines depending on the target being built (not the same lists of defines for MODEL_A as for MODEL_B):
#if defined(MODEL_A)
#define HAS_FUNCTIONALITY_1
#define HAS_FUNCTIONALITY_2
#elif defined(MODEL_B)
#define HAS_FUNCTIONALITY_3
#define HAS_FUNCTIONALITY_4
#endif
My issue with Doxygen:
I try to generate documentation with Doxygen. I have in the Doxyfile:
# including of config.h to INPUT seems necessary.
INPUT = ./source/config.h \
./source
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
INCLUDE_PATH = ./source
INCLUDE_FILE_PATTERNS = ./source/config.h
PREDEFINED = MODEL_A
The code that is dependent on the defines HAS_FUNCTIONALITY_x is not included in the documentation, as if the preprocessor did not get the defines in config.h.
My findings so far:
I inspected the preprocessor output with help of doxygen -d Preprocessor, and could see that:
./source/config.h was parsed first, and correctly according to MODEL_A (I can see the correct #defines in the preprocessor output). #define HAS_FUNCTIONALITY_1 figures in the preprocessor output.
the preprocessing of C files which depend on HAS_FUNCTIONALITY_1 act as if it was not defined.
Defining HAS_FUNCTIONALITY_1 in the field PREDEFINED of the Doxyfile works as expected. This is not a practical solution, but still interesting.
How do I make sure that the #define rows that are preprocessed first from config.h stay defined when the preprocessor works on all subsequent C files?
It would probably be beneficial for you to show the C code itself. In general, Doxygen runs a standard preprocessor - i.e. the rendered code should be the same as if the compiler preprocessed it. In order to achieve the equivalent of #define HAS_FUNCTIONALITY_1 in the code - it has to be defined.
I understand from your reluctance to add it to the doxygen configuration that it is defined somewhere else in the project (or perhaps the Makefile) and that that is the reason that the actual code acts as though it was defined.
If this is the case, I don't see a plausible workaround other than more preprocessor trickery or simply adding it in the doxygen config file.
I ran into a very similar issue.
My headers were in a different directory from my source, e.g.:
doxy_input_dir/
|
+ src/
|
+ inc/
I had RECURSIVE input file option set to YES. I assumed the preprocessor would correctly find my headers. However, when I viewed the preprocessor output by running doxygen -d Predefined <doxyfile> I saw a lot of #include foo.h: not found! skipping....
The solution was to specify all of the header directories explicitly using the INCLUDE_PATH tag.

Conditional compilation: compile once if macro is present at least once

I'm writing a C program and would like to write a function so that, if a certain macro is used at least once, the function is compiled in the object file exactly once.
I was thinking of something in these lines:
#define CERTAIN_MACRO \
...some code here... \
#include "myfunction.h"
(adding my function code in myfunction.h, with suitable include guards in order to prevent multiple inclusion), or
#define CERTAIN_MACRO \
...some code here... \
#define USE_MY_FUNCTION
#ifdef USE_MY_FUNCTION
my function code
#endif
But neither works, because #define and #include are not allowed in macro-expanded code. Any suggestions?
Let the linker do the job it's meant to.
Place the function into its own source file and then build that into a library, say liboptional.a.
When it comes time to create the executable, use that library, for example:
gcc -o execfile file1.o file2.o -loptional
At the time the linker sees the -l optional, it will use the objects within that library to satisfy undefined references. Hence, if you're used the function in file1.o or file2.o, it will be included.

Resources