Вы объявляете функции, специфичные для вашего модуля, статическими?

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

Что вы думаете об этом?

Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
Принципы ООП в JavaScript
Принципы ООП в JavaScript
Парадигма объектно-ориентированного программирования имеет 4 основных принципа,
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Можете ли вы объяснить разницу между ngOnInit и конструктором в Angular?
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
11
0
3 270
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

Если под «модулем» вы имеете в виду просто файл CPP, вы можете просто поместить декларацию и определение прямо в файл CPP.

Это на самом деле не мешает генерации внешнего символа, поэтому он все еще может конфликтовать с одним из другого «модуля».

Evan Teran 24.11.2008 19:09
Ответ принят как подходящий

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

Для C++ лучше, чем static, - поместить его в безымянное (анонимное) пространство имен. Это предпочтительный способ предотвратить загрязнение глобального пространства имен.

namespace {
void myLocalFunction() {
// stuff
}
}

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

Johannes Schaub - litb 24.11.2008 19:27

+1, дополнительную информацию можно найти в этой ветке SO: stackoverflow.com/questions/154469/…

luke 24.11.2008 19:43

Недостаток в том, что это не полезно в C. Вопрос был о c / C++

Ilya 24.11.2008 21:38

Я не заметил тега C. Это решение только для C++.

KeithB 24.11.2008 23:20

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

KeithB 25.11.2008 05:30

Одна проблема с анонимными пространствами имен: у некоторых отладчиков возникают проблемы с установкой точек останова по имени функции, когда вы их используете.

user3458 25.11.2008 16:11

@kshahar: static не является устаревшим. Тот, кто предлагал это, довольно быстро понял / получил ответ, насколько они были неправы, и static остается первоклассной функцией, как и всегда.

underscore_d 25.09.2016 12:24

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

В C++ вы должны использовать анонимное пространство имен, например:

// foo.cpp
namespace
{
   class Core { ... };
   void InternalFandango(Core *);
}

void SomeGloballyVisibleFunction()
{
   InternalFandango(&core);
}

Преимущество: это применимо и к объявлениям структур / классов. В C просто отметьте функции «статическими». Нет ничего против использования «static» в C++, но я научился отдавать предпочтение пространству имен, поскольку это единая концепция, которая работает для всех объявлений.

Да - это неправильно - вы должны отредактировать свой ответ, чтобы исправить это - иначе вас могут отклонить!

Richard Corden 24.11.2008 21:30

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

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

Много было о деталях реализации и не слишком много о концепции.

Ограничение объема переменной / функции и т. д. Действительно является хорошей практикой. Это основная концепция объектно-ориентированного дизайна - вы хотите, чтобы конфиденциальность оставалась конфиденциальной. Таким образом ваш интерфейс станет чище, а обслуживание кода станет проще. И вы не найдете ни одного дня, чтобы изменение чего-то, что вы считали частной компиляцией, сломалось, потому что кому-то в другой части проекта понравилась ваша функция и он решил ее использовать.

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

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

Ilya 25.11.2008 22:00

@ Илья: согласен. Я стараюсь делать вещи тоже константными, когда это возможно. Так получилось, что большая часть моей работы не связана с потоками. Однако я стараюсь избегать глобальных переменных; Я также стараюсь избегать статических переменных как в области файлов, так и в функциях, где это возможно.

Jonathan Leffler 26.11.2008 08:32

В коде C сделайте ваши функции статическими по умолчанию. Делайте нестатические функции и объявления .h только для функций, которые потребуются другим модулям.

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

Я не знаю, почему g ++ вообще записывает тела не вызываемых функций, которые находятся в анонимных пространствах имен, в вывод, но это так. Кажется, также появляются функции со скрытой видимостью; помечены как скрытые символы, но по-прежнему создают неиспользуемые блоки кода в объектном файле. GCC, вероятно, не понимает, что код в таких случаях не нужен. Или я чего-то упускаю, всегда возможно.

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

underscore_d 25.09.2016 12:29

Если вы используете GCC, вам следует взглянуть на флаг видимости (полное обсуждение см. В http://gcc.gnu.org/wiki/Visibility).

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

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

В C++ вы бы объявили функцию частной следующим образом:

class MyClass
{                           
public:                 
void publiclyAccessibleFunction();            
private:                
    void onlyAccesibleFromWithinTheClass();
int some_member_parameter;          
};

Обратите внимание на функцию onlyAccesibleFromWithinTheClass().

OP говорил о модулях, т.е. отдельно скомпилированных исходных файлах и их заголовках, а не об объектах.

underscore_d 25.09.2016 12:31

Согласовано. Как следствие, прототипы статических функций должны располагаться в верхней части файла .c, а не в файле .h.

Другие вопросы по теме