Внутренние функции класса
От: Igore Россия  
Дата: 15.01.19 15:33
Оценка: +1
Добрый вечер, возник тут у меня вопрос, а как вы оформляете внутренние(служебные, чистые) функции класса.

Вот некоторые реализации, которые я встречал
1) Просто делаем private: someFunction(); и это соответственно идет в .h, минус никому кроме класса не нужно, будет включаться везде кто использует этот класс
2) Делаем class_inl.h включаем его в cpp, все функции помечаем inline, минус, нет гарантии что они заинлайнятся, появляется новый файл в проекте
3) В cpp делаем
  Скрытый текст
namespace {
namespace tmp {

void inner()
{
}

}
}

void Test::foo()
{
   tmp::inner();
// other code
}

Минусы, не знаю, встроится вызов функции или нет.
Плюсы, h чистый, все должно остаться в cpp
4) Увидел сейчас в исходника Qt-a, в cpp
  Скрытый текст
static inline inner()
{
}

void Test::foo()
{
   inner();
// other code
}

Вроде как все отлично, все должно встроится, хотя она и помечена как static.
Плюсы, h чистый, все должно остаться в cpp

Хочется совета, кто что использует или что было бы хорошо использовать.
Отредактировано 15.01.2019 15:34 Igore . Предыдущая версия .
Re: Внутренние функции класса
От: rg45 СССР  
Дата: 15.01.19 15:57
Оценка: +3
Здравствуйте, Igore, Вы писали:

I>Добрый вечер, возник тут у меня вопрос, а как вы оформляете внутренние(служебные, чистые) функции класса.


Если это просто чистая функция, которой не нужен доступ к членам класса, то прямо в сипипи-шнике, в анонимном пространстве имен. При этом "static" и "inline" являются избыточными.
--
Re[2]: Внутренние функции класса
От: _NN_ www.nemerleweb.com
Дата: 15.01.19 17:34
Оценка: 3 (2) +1
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, Igore, Вы писали:


I>>Добрый вечер, возник тут у меня вопрос, а как вы оформляете внутренние(служебные, чистые) функции класса.


R>Если это просто чистая функция, которой не нужен доступ к членам класса, то прямо в сипипи-шнике, в анонимном пространстве имен. При этом "static" и "inline" являются избыточными.


Я вот пришёл к выводу, что лучше static, чем анонимное пространство имён.

Тогда в отладчике WinDbg можно легко найти функцию и поставить точку остановки.
С анонимным пространством имён получается имя вроде `anonymous namespace1`::f и отладчик не знает что с этим делать.

К тому же есть и проблемы в VS: https://docs.microsoft.com/en-us/visualstudio/debugger/expressions-in-the-debugger?view=vs-2017#anonymous-namespaces

Anonymous namespaces are not supported. If you have the following code, you cannot add test to the watch window:

http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Внутренние функции класса
От: serg_joker Украина  
Дата: 15.01.19 20:30
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Я вот пришёл к выводу, что лучше static, чем анонимное пространство имён.

...

Поддерживаю. Кроме технических ограничений, когда есть более 1 ф-ции/переменной со внутренним связыванием, я предпочитаю видеть эту информацию для каждого объявления/определения, а не для блока. Вот перешёл я через go-to-definition к какой-то ф-ции — и сразу вижу, что она чисто в этом модуле используется, могу без проблем менять интрерфейс, зная, что она снаружи модуля не видна. С unnamed namespace в такой ситуации нужно глядеть выше по контексту.
Re[3]: Внутренние функции класса
От: rg45 СССР  
Дата: 15.01.19 21:30
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Я вот пришёл к выводу, что лучше static, чем анонимное пространство имён.

_NN>Тогда в отладчике WinDbg можно легко найти функцию и поставить точку остановки.
_NN>С анонимным пространством имён получается имя вроде `anonymous namespace1`::f и отладчик не знает что с этим делать.
_NN>К тому же есть и проблемы в VS: https://docs.microsoft.com/en-us/visualstudio/debugger/expressions-in-the-debugger?view=vs-2017#anonymous-namespaces
_NN>

_NN>Anonymous namespaces are not supported. If you have the following code, you cannot add test to the watch window:


Зато анонимные пространства имен позволяют определять не только функции, но и вообще любые имена с внутренним связываением — классы, перечисления... Тут уже кому что важнее.
--
Re[2]: Внутренние функции класса
От: B0FEE664  
Дата: 15.01.19 21:34
Оценка:
Здравствуйте, rg45, Вы писали:

I>>Добрый вечер, возник тут у меня вопрос, а как вы оформляете внутренние(служебные, чистые) функции класса.

R>Если это просто чистая функция, которой не нужен доступ к членам класса, то прямо в сипипи-шнике, в анонимном пространстве имен. При этом "static" и "inline" являются избыточными.

Почему inline является избыточным?
И каждый день — без права на ошибку...
Re[4]: Внутренние функции класса
От: rg45 СССР  
Дата: 15.01.19 21:34
Оценка: +1
Здравствуйте, serg_joker, Вы писали:

_>Поддерживаю. Кроме технических ограничений, когда есть более 1 ф-ции/переменной со внутренним связыванием, я предпочитаю видеть эту информацию для каждого объявления/определения, а не для блока. Вот перешёл я через go-to-definition к какой-то ф-ции — и сразу вижу, что она чисто в этом модуле используется, могу без проблем менять интрерфейс, зная, что она снаружи модуля не видна. С unnamed namespace в такой ситуации нужно глядеть выше по контексту.


Ну анонимные пространства имен ведь не обязательно делать монолитными блоками. Даже наоборот, если определять фунции попближе к месту их использования, как рекомендуют ведущие собаководы, то и код читать легче, и с определением области видимости проблем не возникает, как правило.
--
Re[3]: Внутренние функции класса
От: rg45 СССР  
Дата: 15.01.19 21:37
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

BFE>Почему inline является избыточным?


Ну от ключей компиляции зависит, если быть точным. Типовые настройки таковы, что компилятор и так будет инлайнить функции там, где посчитает это целесообразным ("any suitable" — в msvc). И в этом ему можно доверять, по моему опыту.
--
Отредактировано 15.01.2019 21:38 rg45 . Предыдущая версия .
Re: Внутренние функции класса
От: Videoman Россия https://hts.tv/
Дата: 15.01.19 21:44
Оценка: 4 (1)
Здравствуйте, Igore, Вы писали:

I>Добрый вечер, возник тут у меня вопрос, а как вы оформляете внутренние(служебные, чистые) функции класса.


Если кратко, то 2, 3, 4, в зависимости от ситуации. 1-й случай почти всегда "не вариант", так как "чистые" функции работают с деталями реализации (могут использовать дополнительные зависимости), которые, по возможности, не должны быть видны снаружи и не должны засорять интерфейс класса. Обычно это детали реализации и не нужно их светить лишний раз.

3, 4 — второй по распространенности случай. Если нужно чтобы функция встраивалась, по возможности, то — static inline, иначе — static. Мне static удобен тем, что сначала я набиваю объявления функций в начале файла, потом идет реализация класса использующая функции, а уже потом я реализую сами функции. В случае static — VС, например, "ругается" что отсутствует реализация, что полезно. Так можно быстренько "накидать" реализацию класса, не задумываясь о деталях.

2-ой метод включает 3-й и 4-й. Но я использую его только если реализация "чистых" функций класса уж очень сложная, комплексная, файл начинает разрастаться и затрудняется навигация по коду или несколько родственных классов начинают дублировать функциональность "чистых" функций.
Re[3]: Внутренние функции класса
От: landerhigh Пират  
Дата: 15.01.19 23:03
Оценка: +1
Здравствуйте, _NN_, Вы писали:

_NN>Я вот пришёл к выводу, что лучше static, чем анонимное пространство имён.

_NN>Тогда в отладчике WinDbg можно легко найти функцию и поставить точку остановки.

А можно наконец переехать в 21 век и начать писать тесты. Юнит-тесты, функциональные тесты и прочие...
www.blinnov.com
Re[4]: Внутренние функции класса
От: _NN_ www.nemerleweb.com
Дата: 16.01.19 05:32
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Здравствуйте, _NN_, Вы писали:


_NN>>Я вот пришёл к выводу, что лучше static, чем анонимное пространство имён.

_NN>>Тогда в отладчике WinDbg можно легко найти функцию и поставить точку остановки.

L>А можно наконец переехать в 21 век и начать писать тесты. Юнит-тесты, функциональные тесты и прочие...


Хотите сказать, что отладчиком не пользуетесь никогда ?
Никакие тесты не могут покрыть все случаи.

Вот, например, был на компе у клиента вирус , который портил выравнивание стека, а удалять вирус клиент не был готов.
Никакие тесты тут не помогут.
Как поняли, что происходит , добавили обход проблемы и тест для него.

Или ошибки других программ, как например антивирусов. Как это тестировать предлагаете ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Внутренние функции класса
От: landerhigh Пират  
Дата: 16.01.19 09:59
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>>>Я вот пришёл к выводу, что лучше static, чем анонимное пространство имён.

_NN>>>Тогда в отладчике WinDbg можно легко найти функцию и поставить точку остановки.

L>>А можно наконец переехать в 21 век и начать писать тесты. Юнит-тесты, функциональные тесты и прочие...


_NN>Хотите сказать, что отладчиком не пользуетесь никогда ?


При разработке, а вышеотквоченное "помогает" только при "отладке" во время разработки (на самом деле — разработке по-ковбойски) — никогда.
Это если не начинать разговор о том, что static исключает инлайнинг, что может быть важно, когда отлавливаешь микросекунды.

_NN>Никакие тесты не могут покрыть все случаи.


И поэтому их писать вообще не надо, да? Старо как мир.

Как раз правильно написанные тесты покрывают абсолютно все возможные случаи для тестируемого юнита. Чего отладчиком не проверить никогда. При этом они прогоняются при каждой сборке и являются первой стадией верификации ака регрессивного тстирования, что вручную отладчиком... ну даже несерьезно обсуждать.
И даже когда изначально поленился покрыть все сценарии в тестах, наличие уже покрытых тестами сценариев позволяет методом исключения найти проблему намного быстрее.

_NN>Вот, например, был на компе у клиента вирус , который портил выравнивание стека, а удалять вирус клиент не был готов.

_NN>Никакие тесты тут не помогут.
_NN>Как поняли, что происходит , добавили обход проблемы и тест для него.

А если у него в серверной пожар, который он тушить не готов, то вы тоже напишете обход?

_NN>Или ошибки других программ, как например антивирусов. Как это тестировать предлагаете ?


Не поверишь, но во многих случаях это тоже можно выявлять и доказывать тестами.
www.blinnov.com
Re: Внутренние функции класса
От: SaZ  
Дата: 16.01.19 12:58
Оценка: 3 (1) +1
Здравствуйте, Igore, Вы писали:

I>Добрый вечер, возник тут у меня вопрос, а как вы оформляете внутренние(служебные, чистые) функции класса.


I>...

I>Вроде как все отлично, все должно встроится, хотя она и помечена как static.
I>Плюсы, h чистый, все должно остаться в cpp

I>Хочется совета, кто что использует или что было бы хорошо использовать.


У анонимных пространств имён, впрочем, как и у статических функций, есть недостаток. На некоторых проектах для ускорения сборки используется так называемая техника unity builds, когда билд система создаёт один (или несколько, в зависимости от количества ядер) .cpp файл, в который уже включаются все остальные .cpp файлы из проекта. Так вот, при использовании такой техники возможнны конфликты имён. Мы с таким сталкивались, когда начали использовать cotire.
Re[2]: Внутренние функции класса
От: Videoman Россия https://hts.tv/
Дата: 16.01.19 13:08
Оценка: 1 (1)
Здравствуйте, SaZ, Вы писали:

SaZ>У анонимных пространств имён, впрочем, как и у статических функций, есть недостаток. На некоторых проектах для ускорения сборки используется так называемая техника unity builds, когда билд система создаёт один (или несколько, в зависимости от количества ядер) .cpp файл, в который уже включаются все остальные .cpp файлы из проекта. Так вот, при использовании такой техники возможнны конфликты имён. Мы с таким сталкивались, когда начали использовать cotire.


А как в таком случае спасают static функции, ведь они тоже не обязаны быть уникальными для разных .cpp ?
Re[3]: Внутренние функции класса
От: SaZ  
Дата: 16.01.19 13:42
Оценка:
Здравствуйте, Videoman, Вы писали:

V>А как в таком случае спасают static функции, ведь они тоже не обязаны быть уникальными для разных .cpp ?


Так я же и написал, что не спасают. В нашем случае поступали очень просто, в большинстве случаев делали static private функции внутри класса. Да, интерфейс загаживался, но это было не критично.
Отредактировано 17.01.2019 2:19 SaZ . Предыдущая версия .
Re[2]: Внутренние функции класса
От: rg45 СССР  
Дата: 16.01.19 13:57
Оценка: +5 :)
Здравствуйте, SaZ, Вы писали:

SaZ>У анонимных пространств имён, впрочем, как и у статических функций, есть недостаток. На некоторых проектах для ускорения сборки используется так называемая техника unity builds, когда билд система создаёт один (или несколько, в зависимости от количества ядер) .cpp файл, в который уже включаются все остальные .cpp файлы из проекта. Так вот, при использовании такой техники возможнны конфликты имён. Мы с таким сталкивались, когда начали использовать cotire.


Как по мне, то нафиг-нафиг такие ускорения.
--
Re[2]: Внутренние функции класса
От: PavelCH  
Дата: 16.01.19 14:52
Оценка: +1
V>Если кратко, то 2, 3, 4, в зависимости от ситуации. 1-й случай почти всегда "не вариант", так как "чистые" функции работают с деталями реализации (могут использовать дополнительные зависимости), которые, по возможности, не должны быть видны снаружи и не должны засорять интерфейс класса. Обычно это детали реализации и не нужно их светить лишний раз.
А почему не вариант? Может просто объявить private функцию и не порождать монстров? Стоит ли игра свеч?
Нехай щастить
Re[3]: Внутренние функции класса
От: SaZ  
Дата: 17.01.19 02:17
Оценка:
Здравствуйте, rg45, Вы писали:

R>Как по мне, то нафиг-нафиг такие ускорения.


Ну мы всякое пробовали. Изначально была ситуация, когда билды игры под андройд могли занимать до 9 часов. Решали всевозможными путями. Прикручивали PCH, поняли что фигня. Делали самописные кэши для текстур, что очень помогало. Увеличивали зоопарк билд серверов. Пробовали Incredibuild, ccache (который пропатчили для нормальной работы под винду). В конечном счёте все махинации, включая юнити билды сделал сборку за приемлемое время: от 4 минут в лучшем случае до 20 минут с конвертацией всех текстур.
Re[4]: Внутренние функции класса
От: rg45 СССР  
Дата: 17.01.19 07:41
Оценка:
Здравствуйте, SaZ, Вы писали:

SaZ>Ну мы всякое пробовали. Изначально была ситуация, когда билды игры под андройд могли занимать до 9 часов. Решали всевозможными путями. Прикручивали PCH, поняли что фигня. Делали самописные кэши для текстур, что очень помогало. Увеличивали зоопарк билд серверов. Пробовали Incredibuild, ccache (который пропатчили для нормальной работы под винду). В конечном счёте все махинации, включая юнити билды сделал сборку за приемлемое время: от 4 минут в лучшем случае до 20 минут с конвертацией всех текстур.


А каков вклад юнити билдов в общее ускорение, можно как-то оценить? Вот если убрать только их, какое время сборки получится?
--
Re[5]: Внутренние функции класса
От: SaZ  
Дата: 17.01.19 13:15
Оценка:
Здравствуйте, rg45, Вы писали:

R>А каков вклад юнити билдов в общее ускорение, можно как-то оценить? Вот если убрать только их, какое время сборки получится?


С ходу не вспомню, это года 3 назад было. Я спрошу у бывших коллег, потом отпишусь. Сборка основного движка вместе с thirdpary примерно в 10 раз, сборка Qt редактора примерно в 2-3 раза.
Надо понимать, что это в первую очередь актуально для сборки с нуля на билд серверах. Мы отказались от PCH, потому что с ним не дружил IncrediBuild.
Основной прирост достигался, насколько я помню, не для скорости компиляции а для скорости линковки.
Отредактировано 17.01.2019 15:44 SaZ . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.