Blue Magister
Blue Magister

Reputation: 13363

A variable that is read-only after assignment at run-time?

Fairly new programmer here, and an advance apology for silly questions.

I have an int variable in a program that I use to determine what the lengths of my arrays should be in some of my structures. I used to put it in my header as a const int. Now, I want to fork my program to give the variable different values depending on the arguments given in, but keep it read-only after I assign it at run-time.

A few ideas I've had to do this. Is there a preferred way?

  1. Declare a const int * in my header and assigning it to a const int in my main function, but that seems clunky.
  2. Make it a plain int in my main function.
  3. Pass the variable as an argument when the function is called.
  4. Something else I haven't thought of yet.

Upvotes: 8

Views: 6764

Answers (4)

Nicol Bolas
Nicol Bolas

Reputation: 473517

I'd use a function-static variable and a simple function. Observe:

int GetConstValue(int initialValue = 0)
{
  static int theValue = initialValue;
  return theValue;
}

Since this is a function-level static variable, it is initialized only the first time through. So the initialValue parameter is useless after the first run of the function. Therefore, all you need to do is ensure that the first call of the function is the one that initializes it.

Upvotes: 9

imre
imre

Reputation: 1717

C++ doesn't have a built-in solution for this, but if you really want to make sure that your int is only assigned once, you can build your own special int class:

class MyConstInt
{
public: 
    MyConstInt(): assigned(false) {}
    MyConstInt& operator=(int v)
    {
        assert(!assigned); 
        value = v; 
        assigned = true; 
        return *this; 
    }   
    operator int() const 
    { 
        assert(assigned); 
        return value; 
    }
private: 
    int value; 
    bool assigned; 
}; 


MyConstInt mi; 
//  int i = mi;         //  assertion failure; mi has no value yet
mi = 42; 
//  mi = 43;        //  assertion failure; mi already has a value
int* array = new int[mi]; 

Upvotes: 6

fredoverflow
fredoverflow

Reputation: 263138

When exactly do you know the correct value? If you read it from a file or whatever, you can just say:

const int n = determine_correct_value();

Upvotes: 1

Kerrek SB
Kerrek SB

Reputation: 477100

I'm tempted to say that what you want doesn't make sense. A constant is something that doesn't change its value, not something that maybe changes its value once or twice. If you want a global variable, just make it non-constant.

On the other hand, if you have scope-constant values, you would just declare and initialize them at the same time, following the general C++ guideline to declare as close to the usage site as possible. For example, mark the use of constants in the following local scope:

for (auto it = v.begin(), end = v.end(); it != end; ++it)
{
  const Foo & x = *it;
  const std::size_t n = x.get_number_of_bars();

  // use x and n ...

  const bool res = gobble(x, zip(n));
  if (res && shmargle(x)) { return 8; }
}

Here the compiler may even choose not to generate any special code for the variables at all if their value is already known through other means.

Upvotes: 0

Related Questions