Home > other >  How can a #define from another headder file be used if the headderfile is not included?
How can a #define from another headder file be used if the headderfile is not included?

Time:12-21

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.

  1. Even though projdefs.h did not direclty include FreeRTOSConfig.h, projdefs.h did include some .h file that included FreeRTOSConfig.h. Or maybe projdefs.h did include some .h file that included some .h file that include FreeRTOSConfig.h, etc. (OP did assert: "projdefs.h" does not include any other files for that matter.")

  2. projdefs.h itself or included directly (or indirectly) something that defined configTICK_RATE_HZ and the assertion that FreeRTOSConfig.h was included is incorrect.

  3. 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 #included 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 symbol TickType_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.

  • Related