Dai Haoci
Dai Haoci

Reputation: 209

Question about variables with combination of extern and const

I googled const + extern on the internet, but it seems there isn't really a good answer for my question.

const alone means internal linkage, but if I want to share a const variable among compilation units. Is extern the best choice?

Common solution would be:

//g.h
extern const int MAX;

// g.c
extern const int MAX = 3;

However, this solution has a drawback, like below:

// Say, I want to use this MAX in the same header file.
// g.h
extern const int MAX;
class AClass
{
public: 
    AClass (): i(MAX){}
private:
    int i;
};

Compiler will complain like:"error C2057: expected constant expression".

Is there a solution for this?

Upvotes: 0

Views: 543

Answers (6)

Praetorian
Praetorian

Reputation: 109149

const alone means internal linkage

This is not correct, static indicates internal linkage, const just says the object cannot mutate. Try declaring a variable as

extern static int foo;

Your compiler will complain about conflicting linkage. To share a const between translation units do exactly what you've suggested.

In the header

extern const int MAX;

In the source file

const int MAX = 10; // note you can omit the extern here

Upvotes: 2

Thomas Matthews
Thomas Matthews

Reputation: 57698

Here is a working example that may solve your issue. In summary, define the array size as a constant in a header file. In another header file declare the array as extern. In the example below I reference the array as extern without using an include file for the array.

array_size.hpp

const unsigned int MAX_ARRAY_SIZE = 16;

array.cpp

#include "array_size.hpp"
int array[MAX_ARRAY_SIZE];

main.cpp

#include "array_size.hpp"

// Reference the array from array.cpp
extern int array[MAX_ARRAY_SIZE];

int main(void)
{
  array[1] = 7;
  return 0;
}

The *array_size.hpp* file defines the size, the identifier can be used in other translation units by including the header.

I compiled on Cygwin using:

g++ -I. -o array.exe main.cpp array.cpp

Upvotes: 1

Puppy
Puppy

Reputation: 146930

extern const int MAX;
int i[MAX];

Can't be done. You could do something like

const int MAX = ReadAnIntegerFromTheConsole();

Perfectly valid and legal, but whoopsies- not a constant expression.

Upvotes: 2

Arvid
Arvid

Reputation: 11245

if you want to be able to use your constant at compile time (i.e. size an array by it, without using VLA) it has to be known at compile time, i.e. it cannot have external linkage.

However, you could just declare your constant in your header file, and make it available to anyone including it. Still, that won't have the exact same effect as an external linkage.

// a.h
const int MAX = 3;

// a.cpp
#include "a.h"
int b[a];

Upvotes: 4

brindy
brindy

Reputation: 4695

Why not just use a #define?

#define MAX 3

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 477070

An easy solution for constant integers is to use enums:

// g.h
enum { MAX = 3; }

// g.c

#include "g.h"
static char buf[MAX];

You won't be able to take the address of MAX, but in turn you get this at zero memory cost.

Upvotes: 4

Related Questions