Вопрос о переменных с комбинацией extern и const - PullRequest
0 голосов
/ 05 августа 2011

Я гуглил const + extern в интернете, но, похоже, на мой вопрос не очень хороший ответ.

const само по себе означает внутреннюю связь, но если я хочу поделиться константной переменной среди единиц компиляции. extern лучший выбор?

Общее решение будет:

//g.h
extern const int MAX;

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

Однако, у этого решения есть недостаток, как показано ниже:

// 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;
};

Компилятор будет жаловаться как: «ошибка C2057: ожидаемое постоянное выражение».

Есть ли решение для этого?

Ответы [ 6 ]

4 голосов
/ 05 августа 2011

если вы хотите иметь возможность использовать вашу константу во время компиляции (то есть размер массива по ней, без использования VLA), она должна быть известна во время компиляции, то есть она не может иметь внешнюю связь.Однако вы можете просто объявить свою константу в своем заголовочном файле и сделать ее доступной для всех, включая ее.Тем не менее, это не будет иметь тот же эффект, что и внешняя связь.

// a.h
const int MAX = 3;

// a.cpp
#include "a.h"
int b[a];
3 голосов
/ 05 августа 2011

Простое решение для постоянных целых чисел - использовать перечисления:

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

// g.c

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

Вы не сможете получить адрес MAX, но, в свою очередь,Вы получаете это при нулевой стоимости памяти.

2 голосов
/ 05 августа 2011

const само по себе означает внутреннюю связь

Это не правильно, static указывает на внутреннюю связь, const просто говорит, что объект не может мутировать.Попробуйте объявить переменную как

extern static int foo;

Ваш компилятор будет жаловаться на конфликтующие ссылки.Чтобы разделить const между единицами перевода, сделайте именно то, что вы предложили.

В заголовке

extern const int MAX;

В исходном файле

const int MAX = 10; // note you can omit the extern here
2 голосов
/ 05 августа 2011
extern const int MAX;
int i[MAX];

Не может быть сделано. Вы могли бы сделать что-то вроде

const int MAX = ReadAnIntegerFromTheConsole();

Совершенно верно и законно, но вопли - не постоянное выражение.

1 голос
/ 05 августа 2011

Вот рабочий пример, который может решить вашу проблему. В итоге, определите размер массива как константу в заголовочном файле. В другом заголовочном файле объявите массив как extern. В приведенном ниже примере я ссылаюсь на массив как extern без использования файла включения для массива.

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;
}

Файл * array_size.hpp * определяет размер, идентификатор можно использовать в других единицах перевода, включая заголовок.

Я скомпилировал на Cygwin, используя:

g++ -I. -o array.exe main.cpp array.cpp
0 голосов
/ 05 августа 2011

Почему бы просто не использовать #define?

#define MAX 3
...