неопределенная ссылка на массив констант

A.cpp

const unsigned char whatever[123] = { /* ... */ };

Хиджры

extern const unsigned char whatever[123];

B.cpp

#include "a.h"
unsigned char x = whatever[0];
// error: undefined reference to 'whatever'

Почему я получаю неопределенную ошибку ссылки? Безconst, ошибка исчезнет.

Как мне разделить массив констант между несколькими единицами перевода?

 linello30 мая 2012 г., 14:42
Разве вы не должны объявлять его как const только в заголовке? У вас есть переменная extern в заголовке и та же переменная в cpp ... Я бы написал:extern const unsigned char whatever[] = {'a','b',/*.etc.*/} только в моем заголовке
 Kerrek SB30 мая 2012 г., 14:42
Добавлятьextern также к определению в a.cpp.
 Edward Loper30 мая 2012 г., 15:04
Делаетa.cpp содержать#include "a.h"? Если нет, то вы должны добавить это.

Ответы на вопрос(5)

Решение Вопроса

с которыми сталкиваются люди, просто вы определили заголовочный файл a.h, который объявляет массив const из 123 символов, и присваивает ему внешнюю связь. Когда он включен в файл b.cpp, вы обещаете компилятор, который он найдет в каком-то другом модуле перевода.

Но каждыйconst переменная имеет темный секрет - она заперта в своей определяющей единице перевода, потому что ей неявно дается статическая связь. Вы обещали свой компиляторwhatever будет совместно использоваться несколькими единицами перевода, но на самом деле он лоялен только к одной единице перевода и не любит, когда его разделяют. И, ну, вы знаете, все остальное.

Решить, явно указавextern в файле реализации.

 M.M08 февр. 2018 г., 21:38
constеременные @ могут иметь внешние или внутренние связи, в зависимости от того, как они были впервые объявлены. Неверно утверждать, что каждыйconst переменная имеет внутреннюю связь.
3.5/3

 A name having namespace scope (3.3.5) has internal linkage if it is the name of
 ...
 — an object or reference that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage;
 ...

Варианты как

 const int x = 10;

неявно определены как «статические».

Чтобы сделать их нестатичными (то есть не внутренними), используйте модификатор 'extern' в файле ".c".

Попробуй

extern const unsigned char whatever[123] = { /* ... */ };
 JoeFish30 мая 2012 г., 14:45
Побей меня до этого. Момент поиска в Google вернул ответ здесь.
 fredoverflow30 мая 2012 г., 15:47
Ты имеешь в видуin ".cpp" file файл, верно? Очевидно, у C нет этой проблемы.
 Viktor Latypov30 мая 2012 г., 21:46
Конечно, это файл .cpp. Мы все знаем, что C ++ не является строгим надмножеством

также используйте extern const в вашем файле .
Эт - это случайная SO-тема, которая имеет больше информации. Или гугл "связь в с ++".

 fredoverflow30 мая 2012 г., 15:47
Ты имеешь в видуin your .cpp file файл, верно? Очевидно, у C нет этой проблемы.
 Torp30 мая 2012 г., 16:33
Да, похоже, это одна из несовместимостей с ++ / c. Я не знал об этом, пока вы не задали вопрос, пришлось гуглить

const - это const времени компиляции, например,

const int cc = 100;
int a[cc];

ы можем использовать const для определения массива , но не в C. Поскольку это const, значение которого изменить нельзя, поэтому не требуется делить их между несколькими файлами. Итак, у const есть внутренняя связь.

Чтобы исправить это,a.cpp следует сделать

#include "a.h"

до определенияwhatever.

Если в области видимости нет предыдущего объявления тогдаconst unsigned char whatever[123] = {...}; будет иметь внутреннюю связь. Но еслиa.h включается, тогда определение соответствует предыдущему объявлению. Заголовок определяетwhatever с внешней связью, и определение соответствует имени.

Как уже упоминали другие, вы также можете поставитьextern в определении, чтобы эта ошибка не возникала, если вы забыли#include "a.h". Но все же рекомендуется включать заголовки, которые объявляют все, что мы пытаемся определить публично.

Ваш ответ на вопрос