Это специфический для С вопрос. Я пытаюсь сохранить все возможное в границах модуля перевода, раскрывая только несколько функций через .h
файл. То есть я даю static
связь с объектами на уровне файлов.
Теперь пара функций должна вызываться другими модулями, но не напрямую. Мой модуль / файл / модуль перевода подписывается на другие модули, передавая указатель на функцию. Затем при конкретном событии указатель вызывается с некоторыми аргументами.
Поэтому мне интересно, как сделать так, чтобы эти функции вызывались из какого-то непонятного места.
- Должны ли они быть
static
илиextern
(и выставить их в.h
)? - Должен ли я включить некоторые подсказки в названии функций?
- Или этого достаточно, чтобы оставить комментарий "под названием X"?
c
naming
encapsulation
scope
Vorac
источник
источник
Ответы:
С точки зрения модуля компиляции (файла), единственное, что вас должно волновать, это то, доступна ли функция извне. Доступ к нему означает, что он должен был быть вызван, и вы должны действовать в предположении, что эти вызовы произойдут. Ваша забота о самой функции начинается с ее точки входа. То, как управление происходит в первую очередь, имеет значение только для кода, который делает это возможным.
Поскольку связь в каждой известной реализации CI является символической, все, что вызывает функцию, должно ссылаться на ее символ:
Если вы ошибочно объявить
foo()
, чтоstatic
ваша программа не будет связывать. Если вы объявляете это неstatic
, у вас есть открытая функция, которая не вызывается. Вопросы о том, используется ли функция или нет, могут быть решены путем сброса таблиц символов ваших объектных файлов или поиска ее в источниках.источник
Определите «неясный».
Методы должны быть представлены через четко определенные «интерфейсы», и, как уже предлагал Shivan Dragon, эти «интерфейсы» являются вашими .h файлами. Если вы не дадите другой программе «правильный» заголовочный файл, он не сможет вызвать метод.
static
может быть в порядке, если у вас нет классов [-подобных конструкций], которые содержат данные экземпляра.extern
означает, что вы вообще не реализуете это; реализация "приобретается" из других источников в процессе компоновки.Точно нет.
Такие комментарии, как бы они ни были благонамеренными, устаревают в тот момент, когда вы заканчиваете их писать.
источник
.h
файл. Он вызывает функцию оттуда и дает ей указатель на одну из собственных функций модуля. Позже внешний код вызывает все, что находится по этому указателю. Таким образом, моя функция вызывается кем-то, кто не включает мой заголовочный файл, а я включаю его.extern
ключевое слово избыточно` .Если функции обратного вызова определены в вашем модуле, и пользователь никогда не предоставит одну из своих функций, я думаю, вы можете использовать заполнитель на этапе инициализации. Заполнитель, как правило,
enum
является внутренним, который затем переводится в нужнуюstatic
функцию.источник
Я все равно сделал бы их
static
(они не предназначены для того, чтобы быть связанными и вызванными кем-либо), и отмечал бы их назначение как обратные вызовы, предоставляемые внешним функциям от их имени.static
потому что я пытаюсь скрыть то, что могу скрыть, столько, сколько я могу это скрыть.Отметьте их в их имени, потому что a), комментарии устаревают, и b), в месте, где предоставляется обратный вызов, становится очевидным, что эта функция предназначена для использования таким образом: это в основном делает ее красным флагом для принимать адрес функции, которая не следует соглашению об именах.
источник
Модификаторы области должны использоваться в основном как информация для компилятора, а не как форма «достаточно близкой» документации. В
static
частности, использование компилятора C позволяет сделать функцию непригодной для использования извне модуля, в том числе в качестве обратного вызова - не то, что вам нужно, даже если это может работать с вашим текущим компилятором.Конечно, вы должны добавить комментарий к коду, поскольку вы можете видеть, что это потенциально запутанная ситуация. Все необычное или неожиданное нуждается в подходящем комментарии. Но, как указано в других ответах, комментарии могут стать непрочитанными или устаревшими.
Таким образом, единственная оставленная опция - назвать функцию, чтобы указать, что это обратный вызов. Большинство примеров, которые я видел, используют
_callback
либо_cb
как суффикс, либоcb_
как префикс. Используйте длинную форму, если обратные вызовы необычны в вашем коде, короткую форму, если они распространены.источник