I'm currently working with FreeRTOS, and have noticed something, which i have not encountered before.
The file "projdefs.h" uses a define from the file "FreeRTOSConfig.h" without including "FreeRTOSConfig.h" without including it. "projdefs.h" does not include any other files for that matter.
How is this possible?
The case is shown below:
//projdefs.h
#ifndef pdMS_TO_TICKS
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000U ) )
#endif
//FreeRTOSConfig.h
#ifndef configTICK_RATE_HZ
#define configTICK_RATE_HZ (1000)
#endif
I've tried to google my way to the answer but nothing has been forthcoming.
CodePudding user response:
How can a
#define
from another header file be used if the header file is not included?
Candidate answers.
Even though
projdefs.h
did not direclty includeFreeRTOSConfig.h
,projdefs.h
did include some .h file that includedFreeRTOSConfig.h
. Or maybeprojdefs.h
did include some .h file that included some .h file that includeFreeRTOSConfig.h
, etc. (OP did assert: "projdefs.h" does not include any other files for that matter.")projdefs.h
itself or included directly (or indirectly) something that definedconfigTICK_RATE_HZ
and the assertion thatFreeRTOSConfig.h
was included is incorrect.configTICK_RATE_HZ
was defined by the compiler.
Design tip:
It is often a chore to find where a define
, object, function or constant was declared/defined.
I have found using a common prefix_
for them all inside "same_prefix.h"
to ease this issue.
CodePudding user response:
How can a #define from another headder file be used if the headderfile is not included?
Macro definitions come from one of these sources:
- source files, including headers, read by the compiler
- compiler / standard library built-ins
- compiler command-line arguments
C compilers do not process source files unasked, so a macro definition will be processed from header.h only if the compiler has a reason to read header.h. Usually, that reason is that the compiler processes an #include
directive that directs it to the header. A header can also be named directly as a file to compile, but this will put its contents into their own translation unit, so it's probably not what you're observing. Some compilers also provide a means to specify headers via the command line, such as GCC's -include option, which perhaps fits your definition of "not included". Or not.
It can be the case that you get inclusion of the header in question via an obscure route, such as behind multiple levels of #include
directives, or a reliance on prior #include
directives to have been processed, or from an #include
with a macro-generated header name, or via a symbolic-link-supported different name.
It's also possible to see a macro with the same name and replacement text that would be provided by inclusion of one header resulting from any of
- inclusion of a different header;
- direct definition via command-line argument; or
- as a compiler built-in,
and none of those are well characterized as being from a header that is not included, but they might give that impression.
As for ...
The file "projdefs.h" uses a define from the file "FreeRTOSConfig.h" without including "FreeRTOSConfig.h" without including it. "projdefs.h" does not include any other files for that matter.
... the fact that projdefs.h uses symbols that it does not define, neither directrly nor via including any other files, leads me to suppose that it simply is not a standalone header. It depends on being #include
d only at a point where either
- the macro
pdMS_TO_TICKS
is already defined, or - the macro
configTICK_RATE_HZ
is already defined, and the symbolTickType_t
is defined either as a type designator or as a macro expanding to a type designator
CodePudding user response:
In the beginning of FreeRTOS.h, you will notice:
/* Application specific configuration options. */
#include "FreeRTOSConfig.h"
/* Basic FreeRTOS definitions. */
#include "projdefs.h"
Also, pdMS_TO_TICKS()
macro is not used by the kernel itself. FreeRTOS kernel always uses ticks. The macro is provided for users (we, application developers) only.