Search code examples
cconstants

How to assign a constant value from another constant variable which is defined in a separate file in C?


dummy.h

#ifndef dummy_h
#define dummy_h

extern const int dummy;

#endif

dummy.c

#include "dummy.h"

const int a = 384;        //I modify the question to reflect that 
const int b = 1;          //dummy is the addition of a and b. I cannot
const int dummy = a + b;  //change a and b. Have to stay like this.

//const int dummy = 385; //define dummy in dummy.c to avoid duplicated symbol issue.

foo.h

#ifndef foo_h
#define foo_h

#include "dummy.h"

extern const int foo;

#endif

foo.c

#include "foo.h"

const int foo = dummy + 1; //<--- The problem is that dummy is not a compile-time constant 

main.c

#include <stdio.h>
#include "foo.h"

int main() {
  
  printf("Hello World. foo = %d\n", foo);

  return 0;
}

makefile

all:
    cc main.c dummy.c foo.c -o dummy

clean:
    rm dummy

This is a snapshot of a much larger program that I am currently working on. I understand why I can't use dummy in foo.c. However, I am not sure what will be the more elegant solution to it.

Basically, I want to define dummy variable in dummy.c and foo in foo.c, and at the same time, I need to find a way to initialize foo with dummy in foo.c.

Wonder if this can be done?


Solution

  • It can't be done directly because dummy is only a constant integer and not an integer constant, and only integer constants can be used in initializers for global variables.

    Option 1

    You can do it indirectly with a macro (or enumeration constant) defining the value used to initialize dummy and also then foo:

    In dummy.h

    enum { DUMMY_INITIALIZER = 385 };
    

    In dummy.c

    const int dummy = DUMMY_INITIALIZER;
    

    In foo.c

    const int foo = DUMMY_INITIALIZER + 1;
    

    I'm assuming there's a good reason why you need foo and shouldn't write dummy + 1 everywhere you use foo. One good reason would be that you write foo a lot (more than once?).

    Option 2

    A question, suggested by jamesdlin in a comment:

    Do you really need const int 'variables'?

    (Are constant variables really variables?) Anyway, you could also solve the problem just using enumeration constants:

    In dummy.h

    enum { DUMMY = 385 };
    

    In dummy.c, do not attempt to define dummy; use DUMMY instead.

    In foo.h

    enum { FOO = DUMMY + 1 };
    

    And in main.c, use FOO instead of foo. Since the enumeration values are compile-time integer constants, you don't have the problems distinguishing between integer constants and constant integers.

    See also "static const" vs "#define" vs "enum"?. If you do need to pass pointers to constant integers to functions, you can define an appropriate variable locally:

    void one_function(void)
    {
        const int foo = FOO;
        …
        some_function(&foo);
        …
    }