Вопрос по linker, c++, header, arrays – неопределенная ссылка на массив констант

8

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, ошибка исчезнет.

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

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

Ваш Ответ

5   ответов
10

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

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

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

constеременные @ могут иметь внешние или внутренние связи, в зависимости от того, как они были впервые объявлены. Неверно утверждать, что каждыйconst переменная имеет внутреннюю связь. M.M
4
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] = { /* ... */ };
Побей меня до этого. Момент поиска в Google вернул ответ здесь. JoeFish
Ты имеешь в видуin ".cpp" file файл, верно? Очевидно, у C нет этой проблемы. fredoverflow
Конечно, это файл .cpp. Мы все знаем, что C ++ не является строгим надмножеством Viktor Latypov
1

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

Ты имеешь в видуin your .cpp file файл, верно? Очевидно, у C нет этой проблемы. fredoverflow
Да, похоже, это одна из несовместимостей с ++ / c. Я не знал об этом, пока вы не задали вопрос, пришлось гуглить Torp
0

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

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

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

0

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

#include "a.h"

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

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

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

Похожие вопросы