mandeep
mandeep

Reputation: 283

using compile time constant throws error

in the below program i have used static const int init. But it is throwing error /tmp/ccEkWmkT.o(.text+0x15d): In function check::operation()': : undefined reference tocheck::init'

This error is coming only when used with vector. Can someone please help? what is the exact behaviour??

#include<vector>
#include<iostream>
using namespace std;

class check{
static const int init=1;
public:
    check(){}
    void operation();
};

void check::operation(){
    vector<int> dummy;
    dummy.push_back(init);
}

int main(){
    check ck;
    ck.operation();
}

Upvotes: 4

Views: 153

Answers (3)

Steve Jessop
Steve Jessop

Reputation: 279255

"what is the exact behaviour?"

The problem is that push_back takes a reference parameter. You can use the value of a static const int member variable without providing a separate definition of the object, but you can't use a reference to the object itself (since it doesn't exist). The meaning of "using" the member itself is defined in the section of the standard on the One Definition Rule, 3.2/2.

One fix is to provide a definition in exactly one translation unit:

const int check::init;

If you do this, you can also choose to move the = 1 initialization from the declaration (inside the class) to the definition (outside the class).

Another fix is to create a temporary from the member variable (this only uses the value, it doesn't care where the object is located and hence doesn't care whether it exists), then pass a reference to the temporary:

dummy.push_back(int(init));

Of course there's a potential maintenance issue there, that if the types of init and dummy both change to, say, long long[*], and the value changes from 1 to something bigger than INT_MAX, then you're in trouble. For that reason you could use +init, since the unary + operator also creates a temporary for its result. Readers and future maintainers might be a bit puzzled by it, though.

[*] Supposing your implementation has long long.

Upvotes: 3

Bo Persson
Bo Persson

Reputation: 92261

If you pass it by reference it is "used" and you may have to define in the .cpp file so that it gets an address.

If you just use the value of the constant, you might get away with not defining it.

Upvotes: 0

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361362

You've to provide the definition of the static member outside the class (in .cpp file) as:

//check.h  (same as before)
class check
{
    static const int init=1; //declaration and in-class initialization
public:
    check(){}
    void operation();
};

Then in check.cpp file, do this:

//check.cpp
#include "check.h"

const int check::init;  //definition

Upvotes: 1

Related Questions