2014-10-20 5 views
1

Я переписываю чей-то код, у которого была глобальная переменная, которая полезна во время инициализации, когда Java делает свои обратные вызовы на C и сразу после. Похоже, что они объявили эту переменную в нескольких местах с префиксом extern и один раз без него. Я действительно не понимаю, почему они будут делать это с глобальной переменной (префикс g_), когда я предпочитаю называть ее static и объявлять ее только один раз.Как иметь глобальную переменную в C++

Смогу ли я это сделать или у static есть отрицательные коннотации для безопасности потоков в этом контексте? Основная часть моего кода - C++, но есть некоторые extern 'C' такие вещи, как те функции, на которые вызывает Java.

В настоящее время я не использую extern или static, но я склонен полагать, что именно поэтому я получаю ошибки связывания.

+0

То же самое, что и в C, но лучшая глобальная переменная не является глобальной variab.e – EJP

ответ

3

static не препятствует переменной из дублируется во время компиляция нескольких единиц компиляции. Когда вы связываете эти единицы компиляции, они в конечном итоге будут видеть разные «экземпляры» одной и той же переменной. Другими словами, каждый увидит свою собственную копию.

Полезность extern заключается в том, чтобы избежать этого дублирования. Вы объявляете глобальную (не static) переменную в файле реализации (.c) и объявляете ее как extern по данному заголовочному файлу (.h), который должен быть включен каждым исходным файлом, который зависит от него.

+0

Это звучит хорошо и знакомо. Благодарю. Считаете ли вы приемлемым, что в файле '.cpp' было присвоено (не-внешнее) квалифицированное объявление, так как файл' .c' отсутствует? Да, работает, очень спасибо @jweyrich – John

+0

Прохладный! Конечно, .cpp и .c являются эквивалентными в этом аспекте. – jweyrich

1

Вы можете иметь глобальные переменные в C++, как вы можете в C. Глобальные переменные представляют собой разделяемое состояние, так же как и на C или на любом другом языке, если вы обращаетесь к общему состоянию из нескольких потоков одновременно (с минимум один измененный доступ), вы должны обеспечить синхронизацию.

Спецификация связи extern "C" необходима только в том случае, если вы хотите получить доступ к одной и той же переменной из нескольких единиц перевода, скомпилированных на разных языках, которые используют правила связи C.

(В отличие от C, C++ глобальные переменные могут иметь нетривиальную инициализацию, которая приносит некоторые новые вопросы упорядочения. Но это не имеет значения.)

+0

Я вижу, я боюсь, что не очень хорошо сформулировал свой вопрос, я получаю ошибки компоновщика, которые, как представляется, называют эту переменную , Этот «exern» C «был только для моих java-обратных вызовов, я бы не выбрал его или« extern »для переменных, я полагаю, что это было сделано с некоторыми флагами-компоновщиками в файлах mk, чтобы заставить все единицы компиляции использовать правила связи C ? Я уверен, что вчера это работало, но – John

1

Вы смешивания extern, extern "C" и static

При объявлении обычной переменной или функции в глобальном масштабе, компилятор разоблачить его в качестве «публичного символа»

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

Ключевое слово static перед декларацией делает совершенно противоположное: оно предотвращает публикацию символа, поэтому оно известно только там, где оно было объявлено (или включено), и не может быть extern ред. поэтому вы не получите «уже определенную» ссылку, когда вы объявляете одну и ту же статическую переменную дважды, и она будет объявлена ​​дважды.

и, наконец, переменные типа extern "C" публикуются в соглашении C не в соглашении C++. основное отличие - это то, что называется «перегрузкой». в C++ несколько функций могут иметь одно и то же имя, с разными типами аргументов, поэтому требуется соглашение о сохранении типов в имени функции. в C имя как есть - это общедоступное имя символа.вы должны использовать его, если не хотите использовать C++-функцию из C или любого другого языка или, возможно, даже из другой версии компилятора C++.

Смежные вопросы