Прекращение поддержки ключевого слова static… не более?


89

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

В n3092 это устарело:

Приложение D.2 [depr.static]
Использование ключевого слова static не рекомендуется при объявлении объектов в области пространства имен (см. 3.3.6).

В n3225 это было удалено.

Единственная статья , я мог бы найти несколько неформальной.

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

Кто-нибудь знает, почему его поменяли?


3
Вы объявляете объекты в области пространства имен в C?
Этьен де Мартель

хех, спасибо, нашел, где его достать. Пытался удалить комментарий, но там ты меня обыграл.
Эдвард Стрэндж


1
Это также дает Комитету по C ++ возможность отменить устаревание чего-либо в следующей версии Стандарта :-)
Джеймс МакНеллис

Ответы:


75

В отчетах о дефектах и принятых проблемах стандартного основного языка C ++, редакция 94 до 1012. Не рекомендуется использовать static `, они отмечают:

Хотя в 7.3.1.1 [namespace.un named] указано, что использование ключевого слова static для объявления переменных в области пространства имен не рекомендуется, поскольку безымянное пространство имен обеспечивает превосходную альтернативу, маловероятно, что эта функция будет удалена в какой-либо момент в обозримом будущем. .

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


2
Что ж, похоже, что отказ от поддержки побудит людей использовать вместо этого безымянные пространства имен, что было бы хорошо.
sbi

1
@unaperson: Если по какой-либо другой причине, то потому, что безымянные пространства имен предоставляют тот же механизм для создания переменных, констант, функций и типов, внутренних по отношению к их TU. static class ... , OTOH, работать не будет.
sbi

2
@nbt: потому что вы не можете использовать статические символы в качестве аргументов шаблона и потому что многие новички сочтут статические проще в использовании, а затем не попытаются опробовать <functional> и <algorithm> и др. Быстрая мысль.
Себастьян Мах

3
"потому что вам не нужен шаблонный код с безымянными пространствами имен"? Что за "шаблонный код"? Что-то помимо " namespace {" и " }"?
Towi

2
@ErikAronesty Если у вас есть «локальный класс» в другом файле с тем же именем, вы совершите нарушение ODR.
LF

32

Я постараюсь ответить на ваш вопрос, хотя это старый вопрос, и он не выглядит очень важным (действительно, не очень важным сам по себе ), и на него уже есть неплохие ответы. Причина, по которой я хочу ответить на этот вопрос, заключается в том, что это относится к фундаментальным вопросам стандартной эволюции и проектирования языка, когда язык основан на существующем языке: когда функции языка должны быть устаревшими, удалены или изменены несовместимыми способами?

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

Фактически связь.

В n3092 это устарело:

Устарение указывает на:

  • Намерение удалить некоторые функции в будущем; это не означает, что устаревшие функции будут удалены в следующей редакции стандарта, или что они должны быть удалены «в ближайшее время» или вообще. А нерекомендуемые функции могут быть удалены в следующей версии стандарта.
  • Формальная попытка воспрепятствовать его использованию .

Последний момент важен. Хотя никогда не бывает формального обещания, что ваша программа не будет нарушена, иногда молча, в соответствии со следующим стандартом, комитет должен стараться избегать нарушения «разумного» кода. Устарение должно указывать программистам, что неразумно полагаться на какую-либо функцию .

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

Очень важно сохранить общее подмножество C / C ++, особенно для файлов заголовков. Конечно, staticглобальные объявления - это объявления символа с внутренней связью, и это не очень полезно в файле заголовка.

Но проблема заключается не только в совместимости с C, а в совместимости с существующим C ++: существует множество действующих программ C ++, которые используют staticглобальные объявления. Этот код не только формально легален, он надежен, поскольку использует четко определенные языковые функции в том виде, в котором он предназначен для использования .

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

Точно так же я не собираюсь менять приведение C-стиля doubleна static_cast<double>просто потому, что «приведение C-стиля плохое», так как static_cast<double>добавляет нулевую информацию и нулевую безопасность.

Идея о том, что всякий раз, когда изобретается новый способ сделать что-либо, все программисты спешат переписать свой существующий четко определенный рабочий код, просто безумна. Если вы хотите удалить все унаследованные C уродства и проблемы, вы не меняете C ++, вы изобретаете новый язык программирования. Половина удаления одного использования staticвряд ли сделает C ++ менее C-уродливым.

Изменения кода требуют обоснования, и «старое - плохо» никогда не является оправданием для изменений кода.

Прекращение языковых изменений требует очень веского обоснования. Слегка упрощение языка никогда не является оправданием серьезного изменения.

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

Так что, действительно, это печальная история. Не из-за практических последствий: у него было ровно ноль практических последствий. Но потому, что это показывает явное отсутствие здравого смысла со стороны комитета ISO.


5
Как вы сами указываете, смысл его осуждения состоит в том, чтобы препятствовать его использованию. Тем не менее, вы не утверждаете, что препятствовать его использованию неправильно. Я, конечно, надеюсь, что никто не поощряет людей использовать статические объявления в области имен вместо анонимных пространств имен. Нет, если только им не понадобится кросс-компиляция C.
Никол Болас

2
Меня не особо волнуют люди, использующие глобальную область видимости staticили анонимные пространства имен, я также не поощряю и не обескураживаю. Я хочу сказать, что если вы действительно хотите отговорить людей использовать анонимные пространства имен, вы должны дать им хороший аргумент. На практике я считаю, что в большинстве реализаций сущности, объявленные в безымянном пространстве имен, представляют собой символы, экспортируемые со случайным именем, таким образом увеличивая таблицу экспорта. Сущности, объявленные как staticOTOH, никак не экспортируются. Таким образом, многие люди, основываясь на этом наблюдении, выбирают использование static.
curiousguy

2
« Как вы сами указываете, цель осуждения его состоит в том, чтобы препятствовать его использованию». Смысл отказа от его использования заключается в том, что он может когда-нибудь исчезнуть. Я staticхочу сказать, что область видимости пространства имен никогда не исчезнет, ​​поэтому не рекомендуется ее исключать. « Тем не менее, вы не утверждаете, что препятствовать его использованию - неправильно». Я не видел убедительных аргументов, показывающих, что использование namespace-scope static«неправильно». Исключить его использование только для того, чтобы препятствовать его использованию, неправильно, потому что никто на самом деле не верит, что он исчезнет, ​​и потому что он не убеждает людей в том, что его использование «неправильно».
curiousguy

5
Весь язык «когда-нибудь исчезнет». Избавимся от C ++.
Lightness Races in Orbit

2
«Аналогичным образом, я не собираюсь изменять приведение типов C в стиле double на static_cast <double> только потому, что« приведения в стиле C плохи », поскольку static_cast <double> добавляет нулевую информацию и нулевую безопасность». Моя вечная борьба со многими разработчиками программного обеспечения, которые продолжают жаловаться на мое расторопное использование преобразований в стиле C от одного примитива к другому.
Makogan

14

Устарело или нет, удаление этой языковой функции приведет к нарушению существующих кодов и раздражению людей.

Вся эта статическая устаревшая идея была просто принятием желаемого за действительное в духе «анонимные пространства имен лучше, чем статические» и «ссылки - лучшие указатели». Лол.


1
«Ссылки лучше указатели»? Нет, умные указатели - более умные указатели. Вы не можете использовать ссылки для памяти, выделенной из кучи, эээ, свободного хранилища.
Дэн Бреслау

3
Извините, я забыл закончить это ироничным смайликом.
Максим Егорушкин

2
@Dan: Это именно то, о чем говорится в этом ответе: «принятие желаемого за действительное» в соответствии с аналогичным ошибочным ходом мысли. Неназванные пространства имен являются важной функцией, как и global-scope-static, хотя и по несколько другим причинам, и даже несмотря на то, что они имеют некоторое перекрытие в применимости.
Фред Нурк

@Fred, @Maxim: Извини, если я неправильно понял, или если моя память неисправна. Но я не классифицирую «ссылки являются лучшими указателями» как эквивалентные «анонимные пространства имен лучше, чем статические» как случай принятия желаемого за действительное. Я хорошо осведомлен о попытках сделать последнее приклеенным, но не припомню, чтобы кто-нибудь серьезно предлагал заменить указатели ссылками. Опять же, может быть, не хватает моего собственного осознания.
Дэн Бреслау

1
@DanBreslau: char* foo = new char; char& ref = *foo;То, что вам дан указатель, изначально ничего не говорит о вашей способности использовать ссылки.
Гонки легкости на орбите
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.