Search code examples
cembeddedstm32iar

Multiple inclusions of same files with different preprocessor settings for creation and assigning of variables


I have been running in the an error in regards to creation of variables through the Preprocessor. AppObjdict is loaded with objdict_frm.h and AppObjdict.h together with a define that controls the behavior of macros in objdict_frm.h. AppObjdict.h is an separate addition to objdict_frm.h. But the IAR compilers throws: Error[Pe169] expected a declaration

**AppObjdict.c**

#define PROTOTYPES
 #include "objdict_frm.h"   
 #include "AppObjdict.h"
#undef PROTOTYPES


s_List_Element OD_init[]=
{
#define SET_OD
#include "objdict_frm.h"
#include "AppObjdict.h"
#undef  SET_OD
    0xffff, 0, NULL
};
        
#define RESERVE_RAM
#include <objdict_frm.h>
#include "AppObjdict.h"
#undef  RESERVE_RAM

void Init_Canop_Structures(int* pNetCfg_p)
{
  pNetCfg_p=7;
#define INIT_RAM
  #include <objdict_frm.h>
  #include "AppObjdict.h"
#undef  INIT_RAM
  return;
}

The content is of objdict_frm.h is loaded correctly as well as all the macros that are used for creation of the variables. Yet the content of AppObjdict.h is not loaded and throws and error on the SET_OD section of the initialization. Guards have been removed from both objdict_frm.h and AppObjdict.h, because the same file need to be ran through several times. Why can the data from AppObjdict.h not pass the compiler?

**objdict_frm.h**

#ifdef PROTOTYPES
#define CREATE(a,b)             extern a b[];
#define CREATE_INDEX_VAR(a,b)   extern u_Subindex_Value   a[];
#define CREATE_INDEX_FULL(a,b)  extern s_SubIndex_Element a[];
#define CREATE_INDEX_ROM(a,b)
#endif

#ifdef RESERVE_RAM
 #define CREATE(a,b)             a b[sizeof( b##_init ) / sizeof( a )];
 #define CREATE_INDEX_VAR(a,b)   u_Subindex_Value   a[sizeof( a##_init ) / sizeof( s_SubIndex_Element)];
 #define CREATE_INDEX_FULL(a,b)  s_SubIndex_Element a[sizeof( a##_init ) / sizeof( s_SubIndex_Element)];
 #define CREATE_INDEX_ROM(a,b)
#endif

#ifdef INIT_RAM
 #define CREATE_INDEX_FULL(a,b)  memcpy((BYTE*)a,(BYTE*)a##_init,sizeof(a));
 #define CREATE_INDEX_VAR(a,b)   initram_var_func(&a[0],&a##_init[0].Subindex_Value,sizeof(a##_init)/sizeof(s_SubIndex_Element));
 #define CREATE(a,b)             memcpy((BYTE*)b,(BYTE*)b##_init,sizeof(b));
 #define CREATE_INDEX_ROM(a,b)
#endif

#ifdef SET_OD
 #define CREATE(a,b)
 #define CREATE_INDEX_FULL(a,b)  b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a,
 #define CREATE_INDEX_VAR(a,b)   b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a##_init,
 #define CREATE_INDEX_ROM(a,b)   b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a##_init,
#endif

CREATE_INDEX_FULL (s_dummy_8,                   0x0005)
**AppObjdict.h**

CREATE_INDEX_FULL (s_boardId,                   0x0012);

#undef  CREATE
#undef  CREATE_INDEX_VAR
#undef  CREATE_INDEX_FULL
#undef  CREATE_INDEX_ROM

Note: the amount of CREATE_INDEX_FULL has been reduced as the same operation is done hundreds of times

Thanks in advance

removed guards from the included files changed marcos slightly and cleaned them up


Solution

  • There is something screwy about iar. I'm on a linux x86_64 PC and I'm unable to reproduce your problem.

    I added some tracing with a SHOWME macro.

    From the output (at the bottom), AppObjDict.h is being included multiple times (without any sort of #ifndef guard or #pragma once).

    At a guess ... If you still have issues using my versions, iar defaults to adding an implicit #pragma once to each .h it tries to include. If so, that's [IMO] bad/dumb.


    objdict_frm.h:

    // **objdict_frm.h**
    
    SHOWME(objdict_frm_h_ENTER)
    
    #ifdef PROTOTYPES
    SHOWME(objdict_frm_h_PROTO)
    #define CREATE(a,b)             extern a b[];
    #define CREATE_INDEX_VAR(a,b)   extern u_Subindex_Value   a[];
    #define CREATE_INDEX_FULL(a,b)  extern s_SubIndex_Element a[];
    #define CREATE_INDEX_ROM(a,b)
    #endif
    
    #ifdef RESERVE_RAM
    SHOWME(objdict_frm_h_RESERVE)
     #define CREATE(a,b)             a b[sizeof( b##_init ) / sizeof( a )];
     #define CREATE_INDEX_VAR(a,b)   u_Subindex_Value   a[sizeof( a##_init ) / sizeof( s_SubIndex_Element)];
     #define CREATE_INDEX_FULL(a,b)  s_SubIndex_Element a[sizeof( a##_init ) / sizeof( s_SubIndex_Element)];
     #define CREATE_INDEX_ROM(a,b)
    #endif
    
    #ifdef INIT_RAM
    SHOWME(objdict_frm_h_INIT)
     #define CREATE_INDEX_FULL(a,b)  memcpy((BYTE*)a,(BYTE*)a##_init,sizeof(a));
     #define CREATE_INDEX_VAR(a,b)   initram_var_func(&a[0],&a##_init[0].Subindex_Value,sizeof(a##_init)/sizeof(s_SubIndex_Element));
     #define CREATE(a,b)             memcpy((BYTE*)b,(BYTE*)b##_init,sizeof(b));
     #define CREATE_INDEX_ROM(a,b)
    #endif
    
    #ifdef SET_OD
    SHOWME(objdict_frm_h_OD)
     #define CREATE(a,b)
     #define CREATE_INDEX_FULL(a,b)  b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a,
     #define CREATE_INDEX_VAR(a,b)   b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a##_init,
     #define CREATE_INDEX_ROM(a,b)   b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a##_init,
    #endif
    
    CREATE_INDEX_FULL (s_dummy_8,                   0x0005)
    
    SHOWME(objdict_frm_h_EXIT)
    

    AppObjdict.h:

    // **AppObjdict.h**
    
    SHOWME(AppObjdict_h_ENTER)
    CREATE_INDEX_FULL (s_boardId,                   0x0012);
    SHOWME(AppObjdict_h_EXIT)
    
    #undef  CREATE
    #undef  CREATE_INDEX_VAR
    #undef  CREATE_INDEX_FULL
    #undef  CREATE_INDEX_ROM
    

    AppObjdict.c:

    // **AppObjdict.c**
    
    #define SHOWME(_who)        SHOWME_ ## _who
    
    SHOWME(AppObjdict_c_ENTER)
    
    #define PROTOTYPES
    SHOWME(AppObjdict_c_PROTO)
     #include "objdict_frm.h"
     #include "AppObjdict.h"
    #undef PROTOTYPES
    
    s_List_Element OD_init[]=
    {
    #define SET_OD
    SHOWME(AppObjdict_c_OD)
    #include "objdict_frm.h"
    #include "AppObjdict.h"
    #undef  SET_OD
        0xffff, 0, NULL
    };
    
    #define RESERVE_RAM
    SHOWME(AppObjdict_c_RESERVE)
    #include <objdict_frm.h>
    #include "AppObjdict.h"
    #undef  RESERVE_RAM
    
    void Init_Canop_Structures(int* pNetCfg_p)
    {
      pNetCfg_p=7;
    #define INIT_RAM
    SHOWME(AppObjdict_c_INIT)
      #include <objdict_frm.h>
      #include "AppObjdict.h"
    #undef  INIT_RAM
      return;
    }
    
    SHOWME(AppObjdict_c_EXIT)
    

    I ran it through cpp with cpp -I. -P AppObjdict.c > out

    Here is the output:

    SHOWME_AppObjdict_c_ENTER
    SHOWME_AppObjdict_c_PROTO
    SHOWME_objdict_frm_h_ENTER
    SHOWME_objdict_frm_h_PROTO
    extern s_SubIndex_Element s_dummy_8[];
    SHOWME_objdict_frm_h_EXIT
    SHOWME_AppObjdict_h_ENTER
    extern s_SubIndex_Element s_boardId[];;
    SHOWME_AppObjdict_h_EXIT
    s_List_Element OD_init[]=
    {
    SHOWME_AppObjdict_c_OD
    SHOWME_objdict_frm_h_ENTER
    SHOWME_objdict_frm_h_OD
    0x0005,(sizeof(s_dummy_8_init)/sizeof(s_SubIndex_Element)),s_dummy_8,
    SHOWME_objdict_frm_h_EXIT
    SHOWME_AppObjdict_h_ENTER
    0x0012,(sizeof(s_boardId_init)/sizeof(s_SubIndex_Element)),s_boardId,;
    SHOWME_AppObjdict_h_EXIT
        0xffff, 0, NULL
    };
    SHOWME_AppObjdict_c_RESERVE
    SHOWME_objdict_frm_h_ENTER
    SHOWME_objdict_frm_h_RESERVE
    s_SubIndex_Element s_dummy_8[sizeof( s_dummy_8_init ) / sizeof( s_SubIndex_Element)];
    SHOWME_objdict_frm_h_EXIT
    SHOWME_AppObjdict_h_ENTER
    s_SubIndex_Element s_boardId[sizeof( s_boardId_init ) / sizeof( s_SubIndex_Element)];;
    SHOWME_AppObjdict_h_EXIT
    void Init_Canop_Structures(int* pNetCfg_p)
    {
      pNetCfg_p=7;
    SHOWME_AppObjdict_c_INIT
    SHOWME_objdict_frm_h_ENTER
    SHOWME_objdict_frm_h_INIT
    memcpy((BYTE*)s_dummy_8,(BYTE*)s_dummy_8_init,sizeof(s_dummy_8));
    SHOWME_objdict_frm_h_EXIT
    SHOWME_AppObjdict_h_ENTER
    memcpy((BYTE*)s_boardId,(BYTE*)s_boardId_init,sizeof(s_boardId));;
    SHOWME_AppObjdict_h_EXIT
      return;
    }
    SHOWME_AppObjdict_c_EXIT