Thread: which #define takes precedence if its the same from two .c files?

  1. #1
    Registered User
    Join Date
    May 2013
    Location
    United States
    Posts
    22

    which #define takes precedence if its the same from a .c and .h files?

    Please refresh my memory.. on this...

    If you have filea.c with:

    Code:
    #define MYVAR 91
    and a fileb.h with :
    Code:
    #define MYVAR 25
    which manifest constant takes precedence if both files have source code that use MYVAR?

    For instance, In a project setting when you compile these files to produce the executable, these manifest constants are treated
    like global variables. If that is how they're supposed to work , then which #define is used?

    Thanks.
    Last edited by kjwilliams; 06-25-2013 at 05:44 PM. Reason: mistake....

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You have a few misconceptions, it seems:
    Quote Originally Posted by kjwilliams View Post
    For instance, In a project setting when you compile these files to produce the executable, these manifest constants are treated
    like global variables. If that is how they're supposed to work , then which #define is used?
    They're not treated like global variables. The preprocessor, which handles #defines, is basically a text substitution program. Everywhere that the token MYVAR is encountered, it is replaced by the value (91 or 25). You can see the output if you use GCC by using the -E flag:
    Code:
    $ gcc -Wall -E filea.c
    <snip>
    int main(void)
    {
      printf("MYVAR = %d\n", 91);
      return 0;
    }
    For MSVC++, some hints as to compiler flags may be here (can't say how close this is, since I don't use MSVC++): Header Defines.


    Quote Originally Posted by kjwilliams View Post
    which manifest constant takes precedence if both files have source code that use MYVAR?
    First, you must understand what a translation unit is. Basically, when a .c file is done being preprocessed, that is the translation unit. The result of all the preprocessing, any #includes and conditional preprocessor stuff, will tell you what value gets used. If some file, filex.c, which doesn't define MYVAR, but does include fileb.h, then it uses the value in the .h file. The only problem is when a .c file both defines a constant and includes a file defining the same constant. Multiple .c files being combined, where two different values for MYVAR may come into play, happens at the linking stage. But at that point, all preprocessor stuff has been processed, so MYVAR is no more, only it's literal values exist anywhere.

    As an example of the problem with defining and #including:
    Code:
    $ cat fileb.h
    #define MYVAR 25
    $ cat filea.c
    #include <stdio.h>
    
    
    #ifdef USE_FILEB
    #  include "fileb.h"
    #endif
    
    
    #define MYVAR 91
    
    
    int main(void)
    {
      printf("MYVAR = %d\n", MYVAR);
      return 0;
    }
    $ gcc -Wall -ggdb3 -o filea filea.c
    $ ./filea
    MYVAR = 91
    $ gcc -Wall -ggdb3 -DUSE_FILEB -o filea filea.c
    filea.c:7:0: warning: "MYVAR" redefined [enabled by default]
    fileb.h:1:0: note: this is the location of the previous definition
    That conditional #ifdef says, if the symbol USE_FILEB is defined, then process the include, otherwise don't. Notice that, if I to process the #include, I get a "redefined" error. That is, if filea.c #includes fileb.h, then it's a problem. If not, it uses it's own.

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    They are both used in their own files -- unless you included the header in the file, which makes them the same translation unit.
    Quote Originally Posted by C99 Draft N869
    6.10.3.5 Scope of macro definitions

    #1

    A macro definition lasts (independent of block structure) until a corresponding #undef directive is encountered or (if none is encountered) until the end of the preprocessing translation unit. Macro definitions have no significance after translation phase 4.
    Use #undef MYVAR if you need both at some point.

  4. #4
    Registered User
    Join Date
    May 2013
    Location
    United States
    Posts
    22

    They're not treated like global variables. The preprocessor, which handles #defines, is basically a text substitution program. Everywhere that the token MYVAR is encountered, it is replaced by the value (91 or 25). You can see the output if you use GCC by using the -E flag:
    I use DJGPP which uses GCC, on Windows , is the -E flag a compiler or linker flag?

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > I use DJGPP which uses GCC, on Windows , is the -E flag a compiler or linker flag?
    Option Summary - Using the GNU Compiler Collection (GCC)
    Where is -E listed here.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by kjwilliams View Post
    I use DJGPP which uses GCC, on Windows , is the -E flag a compiler or linker flag?
    Why are you using a compiler that's more than 10 years out of date, and built to work on 386 systems running DOS? Pick something modern. Perhaps Code::Blocks with MinGW, or Pelles C, both of which are currently developed and have good support communities. Or, install a virtual machine running Linux and use the real GCC.


    As for the flag, it's neither compiler nor preprocessor. GCC is a program that incorporates a preprocessor (processes all the # directives, turning a source file into a translation unit), compiler (compiles C code from a translation unit into object code) and a linker, which links several pieces of object code into the final library/executable/whatever. The -E flag is a flag to the overall GCC program, that instructs GCC to only run the preprocessing phase, and output that.

  7. #7
    Registered User
    Join Date
    May 2013
    Location
    United States
    Posts
    22
    Quote Originally Posted by anduril462 View Post
    The -E flag is a flag to the overall GCC program, that instructs GCC to only run the preprocessing phase, and output that.
    Thats all I needed to know, thanks....

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 11-12-2008, 11:00 AM
  2. Can't define object in seperate files
    By cbranje in forum C++ Programming
    Replies: 1
    Last Post: 11-11-2004, 11:17 AM
  3. #define Header files. End Of File Errors.
    By bartybasher in forum C Programming
    Replies: 8
    Last Post: 07-28-2003, 03:03 PM
  4. precedence
    By modec in forum C Programming
    Replies: 3
    Last Post: 05-22-2003, 11:37 AM
  5. precedence
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 03-17-2002, 12:05 PM