Ключевое слово static
при использовании с определением функции говорит о том, что функция имеет область уровня файла. Это означает, что имя функции отображается только внутри самого файла. Ключевое слово static
, используемое в определении функции, изменяет видимость имени функции и не изменяет тип возвращаемой функции.
Таким образом, функция, объявленная static, может возвращать любой тип.
Использование static
для переменной, определенной в теле функции, используется для указания того, что переменная должна быть создана в момент загрузки и запуска приложения. Поэтому, если вы используете модификатор static
для переменной внутри функции, эта переменная не создается в стеке при вызове функции. Он существует независимо от того, когда вызывается функция. Однако видимость переменной находится только внутри функции.
В вашем примере у вас есть функция, возвращающая адрес переменной static
. Вы можете это сделать, однако вы должны понимать, что это использование не является потокобезопасным.Другими словами, все потоки, вызывающие функцию, получат одну и ту же переменную в одной и той же ячейке памяти, а не в их собственной версии переменной.
Вы также должны понимать, что если вы вернете адрес переменной static
, вы также можете вызвать проблемы с реентракцией и рекурсивностью. Причина в том, что переменные в стеке обеспечивают повторное включение и рекурсию, поскольку каждый раз, когда функция вызывается, в стек добавляется новый кадр, поэтому каждый вызов функции имеет свой собственный стек стека, следовательно, свой собственный набор переменных.
Это известная проблема со старой strtok()
функции в библиотеке Standard C, который использовал переменную внутри функции strtok()
поддерживать состояние между вызовами с использованием NULL как строка адреса, где последний вызов strtok()
кончили при разборе строка. Я видел проблему, когда функция, называемая strtok()
, начала синтаксический анализ строки, а затем вызвала другую функцию, которая, в свою очередь, вызывала strtok()
, чтобы начать синтаксический анализ другой строки. Результатом были некоторые действительно странные ошибки и поведение, пока причина не была выяснена.
Использование модификатора static
в глобальной переменной в файле создает глобальную переменную, которая может использоваться несколькими функциями внутри файла. Однако, как и использование статического модификатора имени функции, переменная static
будет обладать видимостью всего файла.
// .. top of a file of C source code
static int aStaticInt = 0; // a static int that can be shared by all functions in the file but is visible only in the file
int aNonStaticInt = 0; // a non static int that is visible outside of the file
static int myStaticFunc (void)
{
// a function that is visible only within the file
}
int myNonStaticFunc (void)
{
// a function that is visible outside the file as well as inside the file
}
'статический символ *' не тип –
На самом деле, 'void' является излишним и делает некоторые компиляторы сломаться. –
@ Prof.Falken, я думаю, что 'fn1 (void)', в C89, по крайней мере, означает, что я объявляю функцию, которая не принимает параметр, в то время как 'fn1()' означает, что параметры неуточнены (то есть в старых когда идея прототипа не была изобретена). Я ошибаюсь? – hbp