Почему ключевое слово "статическое" имеет столько значений в C и С++?
Как известно, ключевое слово static
имеет несколько значений в C. C99 добавило возможность юридически писать
void foo (int arr[static 50])
{
// ...
}
который добавляет к путанице, а С++ имеет статические членные переменные и функции.
Это не было бы так сложно, если бы все виды использования могли быть связаны каким-то образом, но мне трудно найти эту ссылку для некоторых случаев. В частности, почему ключевое слово static
должно использоваться для изменения видимости (привязки) или того, что на самом деле связано с массивом минимального количества элементов.
Итак, существует ли историческая причина злоупотребления ключевым словом static
, или есть секретная ссылка под капотом, которая связывает все его применения?
Ответы
Ответ 1
Добавление новых ключевых слов к языку нарушает обратную совместимость. Таким образом, static
используется, когда его использование может означать что-то (int arr[static 50]
vs int arr[auto 50]
или int arr[extern 50]
) и не может синтаксически отображаться в этом местоположении на основе его использования в предыдущих версиях.
Хотя в этом случае добавление ключевого слова not_less_than
контекстно-зависимое в этой позиции не приведет к поломке предыдущего кода, оно добавит другое ключевое слово (так что простые текстовые редакторы, которые знают ключевые слова, но не знают синтаксис, не будут знать, ключевое слово), и сломать "ключевые слова не чувствительны к контексту" упрощения, сделанные в C.
Ответ 2
Существует очень простой способ запомнить все 3 значения С++ static
, о которых я знаю. static
означает "в значительной степени похожий на глобальную переменную/функцию, но доступную непосредственно в области..."
- "... этот файл", если он находится в глобальной области.
- "... эта функция", если она находится в функции (включая функции-члены). Обратите внимание: если вы делаете классы и лямбды в функции, они все еще находятся в этой области. Лямбда с пустым захватом может получить доступ к статической переменной своей "родительской" функции.
- "... этот класс", если он находится в классе (в том числе объявленном с
struct
). Этот случай немного отличается, поскольку вы можете получить доступ к переменной/функции через объект или путем префикса, но это немного напоминает запрос к классу или его объекту, чтобы предоставить вам доступ к нему, и на самом деле его можно отрицать (с помощью private
). Таким образом, доступ не является "прямым".
В случае представленного синтаксиса массива C99 это совсем другое, и я предполагаю, что он не должен вводить новые ключевые слова, как предлагают другие.
Ответ 3
static
Исходное значение в С++ фактически устарело, заменено на неназванные пространства имен. Единственный способ использования static
в текущем С++-коде должен быть нечленом.
Ответ 4
Я думаю, что причины разные для разных способов использования этого ключевого слова. Если мы используем область видимости функции и область использования в качестве классического С как само собой разумеющееся (это, по крайней мере, аналогичные понятия), первое добавление из темы - это static
в С++, чтобы назвать глобальный член класса.
Я предполагаю, что здесь ярлык состоял в том, что "статические" и "глобальные", казалось, были достаточно близки, и в начале С++ был очень осторожен, чтобы не вводить новые ключевые слова, которые могли бы нарушить существующий код. Поэтому они взяли существующий, который не мог появиться в этом контексте.
Для надстройки C99 для параметров массива, я думаю, все по-другому, потому что static
- это не единственное дополнение. Вы также можете иметь классификаторы типов (const
и volatile
), которые квалифицируют неявный указатель:
void toto1(char str[const 5]);
void toto2(char*const str);
определить совместимые прототипы. Я могу только предположить, что выбор спецификатора класса хранения static
с целью упоминания (минимальная длина массива) рассматривался как естественное расширение этого синтаксиса. Также, вероятно, легко доказать, что это использование было совместимо с остальным языком, аргументируя, где для расширения языка может использоваться спецификатор типа, спецификатор класса хранения не может навредить.
Ответ 5
Верблюд - это лошадь, разработанная комитетом.
http://en.wikipedia.org/wiki/Design_by_committee
ДОБАВЛЕНО:
Члены комитета, участвующие в проекте, консервативны и больше заинтересованы в том, чтобы не нарушать существующий код на С++, чем потенциальную элегантность нового кода.