Nibnat
Nibnat

Reputation: 119

How to use extern variable correctly?

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?

Upvotes: 1

Views: 137

Answers (2)

Jack47
Jack47

Reputation: 194

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.

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

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.:)

Upvotes: 3

Related Questions