1

Q1: I have recently read book C++ Primer, when I read follow:

To substitute the value for the variable, the compiler has to see the variable’s initializer. When we split a program into multiple files, every file that uses the const must have access to its initializer. In order to see the initializer, the variable must be defined in every file that wants to use the variable’s value.

I have a question: when I use a variable defined in other file, I just use extern to declare is enough, why should I must have access to its initializer, so I have done a test:

in main.cpp, I write below:

#include <iostream>

using namespace std;
extern int test;

int main()
{
    cout << test << endl;
    return 0;
}

in test.cpp, I write below:

int test = 100;

and by the way, these two files are added in the same projects, or it will not build successful. When I run them, it print

100

like I expect. But in main.cpp, I don't need to define something like int test = 100 like book said. I don't know who is right.

Q2:

int i = 43;
const int &r = i;
i = 1;    //when i changed, r alse changed

I have tested in gcc 4.7 and visual studio 2013, they both get same result, r changed. Then, what's the point of const? Shouldn't r always be 43?

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Nibnat
  • 119
  • 7
  • 2
    How do you compile `const int &r = i; ` ? – Ôrel Oct 26 '15 at 09:09
  • 1
    The quote from the book mentions `const`. – Some programmer dude Oct 26 '15 at 09:09
  • Regarding your second (and unrelated) question, you *do* know how references work, right? – Some programmer dude Oct 26 '15 at 09:10
  • 2
    @Ôrel That's perfectly valid, it's no different than having a constant reference argument in a function and passing a value or non-constant variable. – Some programmer dude Oct 26 '15 at 09:11
  • @JoachimPileborg sorry, it was flag as `C` and in `C` it is not valid. in `C++` it is ok – Ôrel Oct 26 '15 at 09:14
  • @JoachimPileborg yes, I know it mentions `const`, but why it's different? What's the reason about that? or just because standard says that? – Nibnat Oct 26 '15 at 09:15
  • 1
    How can a compile-time constant be known if the compiler doesn't actually know the constant value? That's what the quote is about. Note that you *can* have `const` variables without knowing the value, but it's no longer a compile-time constant and the compiler can't use the constants value in optimizations. – Some programmer dude Oct 26 '15 at 09:19
  • @JoachimPileborg Thanks, I just read your last comment time by time, but I still don't get your point, can you explain it more generally? – Nibnat Oct 26 '15 at 09:31
  • @JoachimPileborg Hi, maybe I figured out what you say, the usage of extern in my example, the value of variable test(not defined with const) in main.cpp is known after compiler-time(maybe in link-time?), BUT, if I define a variable, say c_test, with const in test.cpp, then c_test is a compiler-time constant, it must be known in compiler-time, can not after compiler-time. But I still can have a const variable without knowing the value(like const int k = f();), but it will no longer a compiler-time constant. That's your point, right? – Nibnat Oct 26 '15 at 10:11

2 Answers2

3

I think the quote from the book means something like the following

const size_t N = 10;

int main()
{
    int a[N];
    //...
}

If the constant N is defined in some other module with specifier extern then in the module with main the compiler does not have an access to the value of the constant and as result it is unable to define the array

extern const size_t N;

int main()
{
    int a[N]; // error: the value N is unknown
    //...
}

By this reason constants have internal linkage that it could be possible to define them in each module where their values are required at compile time.

As for the second question then constant references are used that to prevent modifying the referenced objects using references.

For example if you want that some function would not change your compound object you can declare its parameter as a constant reference to the object.

Also a temporary objects are bound to constant references.

Consider an example

void display_string( const std::string &s )
{
    std::cout << s << std::endl;
}

you may call the function using a character array. For example

display_string( "Hello, World" );

The compiler implicitly converts the string literal to a temporary object of type std::string and binds it to the constant reference of the parameter.

If the parameter would not be declared like constant reference as for example

void display_string( std::string &s );

then the compiler would issue an error.

Using a constant reference it is supposed that the client code will not change the referenced object itself.

That is the client code may look at the object but may not touch it by hands.:)

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

Q1. have access to its initializer means compiler need to known the variable's initializer(definition). You can let compiler achieve that by link main.cpp and test.cpp together. You said that these two files are added in the same projects, so IDE will do that for you. You can find more on this question.

Q2. Compiler don't allow you to change r's value, because it's a reference to a const variable, but i is an integer variable, so you can change it's value.

Community
  • 1
  • 1
Jack47
  • 194
  • 1
  • 8