This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to declare bit global in header file

Hello all,
I'm having problem declaring bit as global in header file to avoid including
extern bit xxx
in other files. I've followed Keil instruction from this link:
http://www.keil.com/support/docs/1868.htm

So far all the variables are good, and I don't have to use
extern type variable xxx
any more. For bit I try to do this:

_DECL bit xxx _INIT(x);

but it doesn't work. Is there any way to get it through? Would it be good to use struct in this case? If so, how should I do this? Any inputs would be greatly appreciated.

Best Regards,
T.L

Parents
  • To Erik,

    The trick where the op use "_DECL" does not work for initialized variables.
    btw what is Init(0) never heard of it I would make it
    unsigned char Err_B = 0;
    
    Erik
    


    Yes, initialize variable as you show will do the job and I have no problem doing that. The point is I just want to avoid listing a bunch of global variables and bit with initial value in the Main.c
    I don't know why, but the cause of warning message is about this part of the header file:

    _DECL bit Capt_Done _INIT(0);
    _DECL bit Toggle_flag _INIT(0);
    _DECL bit Dual_flag _INIT(0);
    _DECL bit AB_On _INIT(0);
    _DECL bit Ready _INIT(0);
    


    If I take these lines out of the file and declare them as global in main.c and use extern bit xxx in files wherever they are used then there are no warnings. My intention is to get rid off the extern type xxx in other files.

    Best Regards,
    T.L

Reply
  • To Erik,

    The trick where the op use "_DECL" does not work for initialized variables.
    btw what is Init(0) never heard of it I would make it
    unsigned char Err_B = 0;
    
    Erik
    


    Yes, initialize variable as you show will do the job and I have no problem doing that. The point is I just want to avoid listing a bunch of global variables and bit with initial value in the Main.c
    I don't know why, but the cause of warning message is about this part of the header file:

    _DECL bit Capt_Done _INIT(0);
    _DECL bit Toggle_flag _INIT(0);
    _DECL bit Dual_flag _INIT(0);
    _DECL bit AB_On _INIT(0);
    _DECL bit Ready _INIT(0);
    


    If I take these lines out of the file and declare them as global in main.c and use extern bit xxx in files wherever they are used then there are no warnings. My intention is to get rid off the extern type xxx in other files.

    Best Regards,
    T.L

Children
  • If I take these lines out of the file and declare them as global in main.c and use extern bit xxx in files wherever they are used then there are no warnings. My intention is to get rid off the extern type xxx in other files.

    what happens if you remobe init from the bit defs

    BTW the init(0) is totally unnecesaty, the code does that automatically in startup.

    Erik

  • Erik,
    Thank you for your input. I did as you suggested but it still doesn't help. Warning messages still pop out everytime I compile the project.

    BTW the init(0) is totally unnecesaty, the code does that automatically in startup.
    


    In this case, for the testing purposes I initialized these bits as 0, and you got the point there as MCU at start up, startup.asm file should take care off the initialization and set them all to 0 as it clears all RAM. My intention was to find a general solution for further usage in case I want to set these bits = 1. So far I'm OK with variables using Keil's approach. Looks like I have to stick with the way I did before as declaring them global in main.c and use extern bit xxx. I will try to dig around and see if I can do anything else with this.

    Best Regards,
    T.L

  • IMO, these "clever" preprocessor tricks are always dubious at best. As this one doesn't even work, perhaps it's best abandoned now?

    Even the Keil article that you cited says, "this is not necessarily recommended"

    But, if you still want to pursue this, you need to check that your macros are actually expanding correctly. For this, try Andy's Handy Hint for Debugging Preprocessor Problems:

    "Most compilers provide a facility to save the Preprocessor output to a file; with Keil C51, it's the PREPRINT command-line option.
    Conventionally, this creates a file with a .i extension.

    "If you have unexplained errors, or suspect that your macros might not be quite working properly, I recommend that you should check this preprocessor listing!"

  • To Andy
    Thank you for you input. Looks like this is not a common practice and somewhat troublesome. I don't like to give up but it seems this practice will cause more trouble than good. As you said, I should abandone the dead horse now. Thank you all for your time and inputs.

    Best Regards,
    T.L

  • "Looks like this is not a common practice..."

    Actually, it's not uncommon

    "... and somewhat troublesome"

    That bit is true!

  • See also: c-faq.com/.../decldef.html

    "It is possible to use preprocessor tricks ... but it's not clear if this is worth the trouble"

  • after wasting plenty of time hunting things like
    char Ralph;
    extern short Ralph;
    of course, in stuff written by others :)
    I have become a firm believer in
    qqq char Ralph;
    where 'qqq' is defined as extern in all modules but one. Of course 'qqq' should be something meaningful - your choice.

    Erik

  • "after wasting plenty of time hunting"

    I still don't think it's proven that messing around with preprocessor tricks will waste any less time when it runs into problems - as this thread amply demonstrates!

    The simple answer to your problem is to ensure that the header with the 'extern' declaration is included in the file with the real definition. That way - and only that way - the compiler can spot any discrepancies!

    declaration.h

    extern short Ralph; // Declaration
    

    reference.c

    #include "declaration.h"
    :
    // stuff using Ralph
    :
    

    definition.c

    #include "declaration.h"
    :
    char Ralph; // Definition - Compiler will warn here!
    

    Even with preprocessor tricks, you still run the risk the the two alternatives might not match - but preprocessor trick will ensure that the compiler can never see the two and, therefore, can never report the discrepancy.

    So, on balance, I rest mu case, m'lud.

  • I do agree that the use of 'preprocessor tricks' should not be "a hobby" and, thus I restrict my use to the #define xxx as extern or nothing, which has proven safe. Where the 'simple trick' does not work, I split like this
    #ifdef "the module that has the definitions"
    blah
    #else
    extern blah
    #endif

    Erik

  • But you are still at risk from typos like

    #ifdef "the module that has the definitions"
    signed blah
    #else
    extern unsigned blah
    #endif
    


    And, because the preprocessor trick ensures that the compiler can never see both, then you are assured that it can never warn you!