anlucki
anlucki

Reputation: 63

C++ global extern constant defined at runtime available across multiple source files

I have an integer constant that is to be defined at runtime. This constant needs to be available globally and across multiple source files. I currently have the following simplified situation:

This works flawlessly with a char * constant that I use to have the name of the program globally available across all files, and it's declared and defined exactly like the one I'm trying to declare and define here but I can't get it to work with an int.

I get first an error: uninitialized const ‘someConstant’ [-fpermissive] at the line I'm declaring it in main.cpp, and later on I get an error: assignment of read-only variable ‘someConstant’ which I presume is because someConstant is getting default initialized to begin with.

Is there a way to do what I'm trying to achieve here? Thanks in advance!


EDIT (per request from @WhozCraig): Believe me: it is constant. The reason I'm not posting MCVE is because of three reasons: this is an assignment, the source is in Spanish, and because I really wanted to keep the question as general (and reusable) as possible. I started out writing the example and midway it striked me as not the clearest question. I'll try to explain again.

I'm asked to build a program that creates a process that in turn spawns two children (those in turn will spawn two more each, and so on). The program takes as single argument the number of generations it will have to spawn. Essentially creating sort of a binary tree of processes. Each process has to provide information about himself, his parent, the relationship with the original process, and his children (if any).

So, in the example above, ClassA is really a class containing information about the process (PID, PPID, children's PIDs, degree of relation with the original process, etc). For each fork I create a new instance of this class, so I can "save" this information and print it on screen.

When I'm defining the relationship with the original process, there's a single point in which I need to know the argument used when calling the program to check if this process has no children (to change the output of that particular process). That's the constant I need from main: the number of generations to be spawned, the "deepness" of the tree.


EDIT 2: I'll have to apologize, it's been a long day and I wasn't thinking straight. I switched the sources from C to C++ just to use some OO features and completely forgot to think inside of the OO paradigm. I just realized while I was explaining this that I might solve this with a static/class variable inside my class (initialized with the original process), it might not be constant (although semantically it is) but it should work, right? Moreover I also realized I could just initialize the children of the last generation with some impossible PID value and use that to check if it is the last generation.


Sorry guys and thank you for your help: it seems the question was valid but it was the wrong question to ask all along. New mantra: walk off the computer and relax.

But just to recap and to stay on point, it is absolutely impossible to create a global constant that would be defined at runtime in C++, like @Jerry101 says?

Upvotes: 4

Views: 2651

Answers (5)

Christian Hackl
Christian Hackl

Reputation: 27528

As others have mentioned, your variable is far from being constant if you set it only at run-time. You cannot "travel back in time" and include a value gained during the program's execution into the program itself before it is being built.

What you can still do, of course, is to define which components of your program have which kind of access (read or write) to your variable.

If I were you, I would turn the global variable into a static member variable of a class with a public getter function and private setter function. Declare the code which needs to set the value as a friend.

class SomeConstant
{
public:
    static int get()
    {
        return someConstant;
    }

private:
    friend int main(); // this should probably not be `main` in real code

    static void set(int value)
    {
        someConstant = value;
    } 

    static int someConstant = 0;
};

In main:

int main()
{
    SomeConstant::set(123);
}

Anywhere else:

void f()
{
    int i = SomeConstant::get();
}

You can further hide the class with some syntactic sugar:

int someConstant()
{
    return SomeConstant::get();
} 

// ...

void f()
{
    int i = someConstant();
}

Finally, add some error checking to make sure you notice if you try to access the value before it is set:

class SomeConstant
{
public:
    static int get()
    {
        assert(valueSet);
        return someConstant;
    }

private:
    friend int main(); // this should probably not be `main` in real code

    static void set(int value)
    {
        someConstant = value;
        valueSet = true;
    } 

    static bool valueSet = false;    
    static int someConstant = 0;
};

As far as your edit is concerned:

Nothing of this has anything to do with "OO". Object-oriented programming is about virtual functions, and I don't see how your problem is related to virtual functions.

Upvotes: 2

anilLuwang
anilLuwang

Reputation: 25

Well, the use of const in C++ is for the compiler to know the value of a variable at compile time, so that it can perform value substitution(much like #define but much more better) whenever it encounters the variable. So you must always assign a value to a const when u define it, except when you are making an explicit declaration using extern. You can use a local int to receive the real value at run time and then you can define and initialize a const int with that local int value.

int l_int;
cout<<"Enter an int";
cin>>l_int;
const int constNum = l_int;

Upvotes: 0

Jerry101
Jerry101

Reputation: 13367

In C/C++, a const is defined at compile time. It cannot be set at runtime.

The reason you can set a const char *xyz; at runtime is this declares a non-const pointer to a const char. Tricky language.

So if you want an int that can be determined in main() and not changed afterwards, you can write a getter int xyz() that returns a static value that gets initialized in main() or in the getter.

(BTW, it's not a good idea to declare the same extern variable in more than one header file.)

Upvotes: 5

Kastaneda
Kastaneda

Reputation: 749

const qualifier means variable must initialized in declaration point. If you are trying to change her value at runtime, you get UB.

Upvotes: 0

Ashwin Subramanya
Ashwin Subramanya

Reputation: 361

char * - means ur creating a pointer to char datatype. int - on other hand creates a variable. u cant declare a const variable without value so i suggest u create a int * and use it in place of int. and if u are passing it into functions make it as const

eg: int *myconstant=&xyz;
   ....  
   my_function(myconstant);
}
//function decleration
  void my_function(const int* myconst)
 {
    ....
 } 

Upvotes: 0

Related Questions