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

global variable/MULTIPLE PUBLIC DEFINITIONS

Hi,
I've split my project into files.
I've defined some global variables in one of the header files as follows:

unsigned char ToneDisp[16] = {'D','1','2','3','4','5','6','7','8','9','0',0x2A,0x23,'A','B','C'};
struct channel xdata Ch[16];
unsigned char CHANNELTYPE[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

These variables are used in other files too.

Compiling the files individually everything goes fine while building the project results in:
*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS

How can I avoid this?
Shouldn't I 've defined the global variable that way??

Thanks for your attention in advance
A.E.

Parents
  • You should not, repeat: not ever define variables in a header file.

    I always define variables in a header file.

    I do like this

    #ifdef VARACT
    #define QQQ
    else
    #define qqq extern
    #endif
    
    ...
    
    #define U8 QQQ unsigned char
    

    The in ONE .c file
    #define VARACT

    This works as a champ and no 'mistakes, of a variable defined as twi different things can occur

    Erik

Reply
  • You should not, repeat: not ever define variables in a header file.

    I always define variables in a header file.

    I do like this

    #ifdef VARACT
    #define QQQ
    else
    #define qqq extern
    #endif
    
    ...
    
    #define U8 QQQ unsigned char
    

    The in ONE .c file
    #define VARACT

    This works as a champ and no 'mistakes, of a variable defined as twi different things can occur

    Erik

Children
  • no 'mistakes, of a variable defined as twi different things can occur

    Perhaps, but lots of "didn't correctly #define, lots of multiple definition" mistakes can occur -- as is the original poster's problem.

    The preprocessor is ugly enough that it's not worth introducing merely to avoid two different definitions. Also, your interface should not change so often that it's really a problem. Even if you need to make a global variable part of the interface to a module, once you choose to do so, that decision is fixed. You shouldn't be updating the definition all the time, any more than you would gratuitiously rename a function constantly.

  • Also, your interface should not change so often that it's really a problem. Even if you need to make a global variable part of the interface to a module, once you choose to do so, that decision is fixed. You shouldn't be updating the definition all the time, any more than you would gratuitiously rename a function constantly.

    When making several 'somewhat similar' projects you do everything stated above that you "do not do" after each 'steal' from the previous project.

    I would, somewhat, agree with Drew if everything you made was started from scratch, but how often do you do that?

    Erik

  • I always define variables in a header file.

    Not really you don't. You just put another layer of cloaking around the fact, using the preprocessor, but at the heart of it, your technique still does what I said has to be done: declare in the header file (i.e. in all "ordinary" uses, in your case), and define in a .c file (the one where you
    #define VARACT).

    Actually, as given, that technique has several drawbacks:

    1) it only works for uninitialized definitions. You'ld need additional hacks to hide the initializers from client modules.

    2) I rather strongly object to #define'ing a type name. The language has the concept of a typedef for a reason.

    3) I would object even stronger to mingling the linkage ("extern" or not) into the type name. For one thing, it makes your 'U8' definition unusable for local variables.

  • 3) I would object even stronger to mingling the linkage ("extern" or not) into the type name. For one thing, it makes your 'U8' definition unusable for local variables.

    I tried to keep it simple, but here we go

    #define U8 unsigned char // for internal use

    define UC qqq U8 // for global variable

    Hans-Bernhard,

    You have your ideas like
    I rather strongly object to #define'ing a type name. The language has the concept of a typedef for a reason

    I honestly don't give a hoot what you do in your place as long as it works for you, In my place I do what works for me.

    There is no reason, whatsoever, to do something in a given way because K&R makes it possible or suggest it as 'proper'. If one way fit you, use it whatever else K&R may have come up with.

    My whole 'system' is based on avoiding pitfalls and if the 'improper' use of headers for variables definition saves me ONE mistake I do not give one dime for the properness of it.

    Erik

    We can continue this discussion with what is correct
    While(1){}
    or for(;;){}
    but let us not, you have your opinion and is welcome to it, I have mine.