Как объявить статическую переменную, но не определить ее

  • константа ключевое слово может использоваться для констант времени компиляции, таких как типы примитивов и строки
  • только для чтения , ключевое слово может использоваться для констант этапа выполнения, таких как ссылочные типы
  • , проблема с только для чтения состоит в том, что это только позволяет ссылке (указатель) быть постоянной. Вещь, на которую ссылаются, (указала), может все еще быть изменен. Это - хитрая часть, но нет никакого пути вокруг этого. Реализовать постоянные объекты означает заставлять их не представить изменяемые методы или свойства, но это является неловким.

    См. также Эффективный C#: 50 Особенных методов Улучшить Ваш C# (Объект 2 - Предпочитают только для чтения константе)

7
задан Prasoon Saurav 4 October 2010 в 02:51
поделиться

6 ответов

gcc выдаст предупреждение в описанном вами случае:

./x.c:3010: warning: 'someName' defined but not used

Решение: делайте то, что вы делаете в данный момент, но не игнорируйте предупреждения компилятора;)

Редактировать:

С вашим обновленным вопросом: Нет, я не верю, что есть способ просто объявить статическую переменную (без ее определения).

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

9
ответ дан 6 December 2019 в 08:15
поделиться

Невозможно создать не определяющее объявление (т. Е. «Предварительное объявление» в вашей терминологии) объекта с внутренней связью на языке C.

Насколько вы можете приблизиться к этому, это предварительное определение , которое у вас есть в вашем примере. Но в случае опечатки предварительное определение неявно даст независимое определение, а не ошибку линкера.

4
ответ дан 6 December 2019 в 08:15
поделиться
static some_type some_name; /*definition */

Статическая переменная some_name была инициализирована значением 0; это определение, а не просто объявление.

ИМО, статическая переменная не может быть просто объявлена ​​в C с использованием спецификатора extern, поскольку ее связь всегда внутренняя.

8
ответ дан 6 December 2019 в 08:15
поделиться

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

Так что поместите свои постоянные defs и статические переменные вверху каждого файла, чтобы ваш инициализатор для статики мог идти сразу после констант. Тогда вам не нужна отдельная строка инициализации.

В любом другом случае caf прав: может быть, стоит заставить ваш код скомпилировать с помощью gcc, просто чтобы получить выгоду от его предупреждений. Я сделал это для g ++ для графического интерфейса MFC на C ++. (компилировать, а не запускать!)

AFAIK C не делает ' У меня есть способ написать слабое определение, которое вызовет ошибку, если позже не будет определения с инициализатором. Всегда присутствует неявный 0, поскольку переменная входит в секцию BSS.

0
ответ дан 6 December 2019 в 08:15
поделиться

Немного предыстории:

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

Когда вы инициализируете глобальную переменную (статическую или нет), компилятор просто помещает начальное значение в исполняемый файл в области памяти, выделенной для переменной. Другими словами, у него всегда есть начальное значение. Конечно, вы всегда можете переопределить значение позже, используя оператор присваивания.

Предложения:

Если вы действительно не знаете значение переменной во время компиляции, вам следует назначить его динамически в вашей функции инициализации. .

static some_type some_variable; /* = 0 by default */

/* some code */

void MyInitializations()
{
    some_variable = some_value;
}

Если вы хотите объявить переменную в одном месте, скажем, в файле заголовка, и определить ее в исходном файле, то вам следует использовать объявление extern, которое сообщает компилятору не беспокоиться о том, где находится переменная. Компоновщик найдет местоположение переменной так же, как он находит функцию в другом файле, и заполнит адрес.

Заголовок:

extern some_type some_variable;

Исходный файл 1:

void UseSomeVariable()
{
    x = some_variable;
}

Исходный файл 2:

some_type some_variable = some_value;

/* possible also uses some_variable */

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

объявление, которое сообщает компилятору не беспокоиться о том, где находится переменная. Компоновщик найдет местоположение переменной так же, как он находит функцию в другом файле, и заполнит адрес.

Заголовок:

extern some_type some_variable;

Исходный файл 1:

void UseSomeVariable()
{
    x = some_variable;
}

Исходный файл 2:

some_type some_variable = some_value;

/* possible also uses some_variable */

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

объявление, которое сообщает компилятору не беспокоиться о том, где находится переменная. Компоновщик найдет местоположение переменной так же, как он находит функцию в другом файле, и заполнит адрес.

Заголовок:

extern some_type some_variable;

Исходный файл 1:

void UseSomeVariable()
{
    x = some_variable;
}

Исходный файл 2:

some_type some_variable = some_value;

/* possible also uses some_variable */

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

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

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

2
ответ дан 6 December 2019 в 08:15
поделиться

Если я понимаю вашу проблему, возможно, вы просто не сталкиваетесь с ней правильный путь.

Разве вам не лучше с extern SomeType someVar _; , который сообщает вашей программе, что я знаю, что эта переменная будет известна, но я не хочу говорить вам, что это такое now.

Таким образом, вы можете объявить свою переменную в отдельном файле say

static SomeType SomeVar _;

В вашем файле поместите

extern SomeType SomeVar_

И затем поместите инициализацию в любое место.

-1
ответ дан 6 December 2019 в 08:15
поделиться