3

Please assume the version of gcc 7.2.1 in this question

I would like to declare a global variable which behave like a const however, the value to initialize it cannot not be detected before the program being executed. In other words, the target variable would be re-assigned since the first time it is assigned.

An ugly approach of this concept as follow:

#include<iostream> int numberOfPeople; //Do not re-assign it after it first assign int main(){ std::cin >> numberOfPeople; // Do not re-assign numberOfPeople since then !!! // Following of codes omitted. } 

As you could see, this is a very ugly approach and cannot be checked by compiler. I wonder whether there is a kind of notation in c++ that can freeze the variable since it first assigned.

So I can write code like this:

#include<iostream> magic_notation int numberOfPeople; int main(){ std::cin >> numberOfPeople; // Allowed as it's first assign. // Median codes omitted. numberOfPeople = 60. //Disallowed and will get an error message from compiler! // Following codes omitted. } 

Is there any kind of notation as can use like the magic_notation in the code above in c++?

7
  • Make it a member of a class that controls access. Commented Dec 22, 2017 at 22:42
  • @neil-butterworth Thanks for your reply. However, could you please give me an example code? Commented Dec 22, 2017 at 22:44
  • I think you are looking for this: stackoverflow.com/questions/35800643/… Commented Dec 22, 2017 at 22:45
  • @EIjay Thanks for your reply. It's similar. However, I would like to find a syntax based solution. Commented Dec 22, 2017 at 22:48
  • 1
    @TJM • I don't think you'd be able to get a compile time error as you had requested. It could just silently ignore subsequent assignments, or throw an exception on subsequent assignments. Commented Dec 22, 2017 at 22:49

3 Answers 3

1

The best approach is to make a class with a public const member variable which gets initialized in the constructor:

struct InitInfo { const int numberOfPeople; InitInfo() numberOfPeople(getNumberOfPeople()) { } private: static int getNumberOfPeople() { int res; cin >> res; return res; } }; InitInfo initInfo; 

Now you can use the member variable as follows:

int main() { cout << initInfo.numberOfPeople << endl; } 

You can use the same approach for initializing a global variable, too.

static int getNumberOfPeople() { int res; cin >> res; return res; } const int numberOfPeople = getNumberOfPeople(); int main() { cout << numberOfPeople << endl; numberOfPeople += 10; // <<== This triggers an error } 
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your reply, so const int numberOfPeople = getNumberOfPeople() is executed before the first line of main()?
@TJM Yes, it will be initialized before entering main.
0

One approach you can use is to wrap the variable as a static variable in a function. Use the function instead of the variable in rest of your code.

#include <iostream> int readFromStdin() { int n; cin >> n; return n; } // Wrap it arund in a function. // int numberOfPeople; //Do not re-assign it after it first assign int getNumberOfPeople() { // Initialize by reading from stdin. static int numberOfPeople = readFromStdin(); returnn numberOfPeople; } int main(){ // Use the function instead of the variable. getNumberOfPeople(); } 

5 Comments

Thanks for your reply, it looks like singleton pattern. However, is there any simpler way to do this?
@TJM No there is not. There isn't a modifier like const which you can simply add to your variable declaration. Perhaps you can find a library that provides a write_once class template or something, so you can write write_once<int> numberOfPeople; and it would work like you intent.
@Justin ...well, technically there is: you could just cast away the const-ness at assignment. Cringe-worthy, I know.
@Dúthomhas, that would be undefined behavior from the get go.
Er, writing to const stuff is undefined behavior IFF we don’t know anything more about the data than its const-on-arrival. OP is asking about data specifically known to be non-const but presented to all as const. It is a fine hair to split, I agree, and again I don’t really recommend it.
0

In case you have different ways to initialize the variable, you could come up with something like this:

struct { int value() const { return _val; } void init(int val) { if(!_set) _val = val; } private: int _val; bool _set = false; } numberOfPeople; 

Now, everybody who uses the variable should call init before using it to make sure it is initialized.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.