LINUX.ORG.RU

История изменений

Исправление byko3y, (текущая версия) :

Как скажешь. Я просто говорю, что у тех, кто на языке активно пишет. Можешь посмотреть используется ли в каких-нибудь свежих проектах const. По твоей логике, все уже должны были осознать, что это бесполезно, а то и вредно. Или это потому что правильных архитекторов спросить забыли?

Я уже писал по этому поводу, могу пояснить еще раз: использование const вынуждает соседний код использовать const, неиспользование const вынуждает соседний код тоже не использовать const. Тем не менее, повесить const проще, чем его убрать.

Да, извини за «токсичность», но сдержаться сложно

Вообще не почувствовал, слабо стараешься.

Ну нет, такого я не писал. Если переменная mutable (а речь изначально шла об этом), то каст не нужен и соответственно UB тоже нет.
Кстати, даже с кастом это не UB, если объект «на самом деле» не константный

И всё это ты будешь проверять руками, как мой любимый strict aliasing, тоже требующий, чтобы все записи были строго по тому же типу, и тоже компилятор никак не может это проверить.

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

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

Второй симптом одержимости агрегатными объектами мы тоже обсудили — это public/private, которые опять же являются комментариями и возникли из-за того, что в один объект начали совать совершенно разнородные сущности, и в какой-то момент это настолько стало нормой, что уже и не считается проблемой, хотя об эти грабли по прежнему стукаются с завидной регулярностью, когда возникает потребность получить доступ к тому, что автор сторонней либы посчитал недоступным пользователю. Как я уже написал ранее, самый грамотный подход, требующий минимальных телодвижений — это сделать отдельный метод, который вываливает все кишки наружу, «это как бы, ну, на этом наши полномочия всё».

А теперь реши проблему 100500 методов, куда передаётся const MyClass&. Или твоё решение сводится к тому, чтобы никогда и нигде не писать const? Жалко, наверное, что множество кода ему не следуют

Если метод принимает const MyClass& и при этом делает уберсложные операции внутри, которые потенциально даже непрямо изменят значение const MyClass& — то ССЗБ, чо. Как я уже написал, «константно, потому что Мейерс так завещал».

Давай раскроем, зачем нужен const MyClass& arg. Я как-нибудь сам смогу убедиться, что не вызову очевидный arg.x = 1. Потому на самом деле const нужен для того, чтобы я случайно не вызвал неконстантный метод arg. Проблема в том, что если arg является агрегирующим объектом, то этой гарантии мы лишаемся, потому что const методы будут менять объект. Конечно же на самом деле мне нужно не просто const/non-const, а некие более тонкие уровни, вроде «вызов не блокирует объект», «вызов читает значение мимо кэша», которые по класссической крестовой методологии возможно сделать ТОЛЬКО на уровне контрактов и ручной их проверки.

Я предложил выше другой подход — это разобрать агрегаты на отдельные части и гарантировать бинарный const отдельно на блокировке, отдельно на кэше, отдельно на данных. Это прежде всего подразумевает, что ты наконец оторвешь методы-интерфейсы от данных и начнешь ими оперировать отдельно, как это должно быть, если мы наконец перестанем пародировать ООП, которого в C++ на самом деле нет, поскольку инкапсуляция течёт где только можно, а позднего связывания и передачи сообщений никогда не было. Не путать парадигму языка с тем, что написано на самом языке, поскольку написать можно хоть лисп на ассемблере — это не делает асм функциональным языком с GC.

В этом случае использовать const_cast в неконстантной функции легально, если очень хочется. Хотя я думаю, что ты и сам это знаешь, а саму «проблему» подсмотрел у Майерса и пришёл в ужас

Мейерс как раз не видит в этом проблемы, и предлагает именно твое решение. У меня к таким авторам неизменно возникает один и тот же вопрос: они когда-нибудь в своей жизни писали хотя бы одну программу больше пары тысяч строк? Как правило, большинство гуру примерно на этой отметке останавливаются, потому что примерно на таких объемах теряется способность досконально помнить каждую буковку кода и начинается настоящее програмирование. В которое они не умеют, но учат других.

А ты не ответил, что же делать с дублированием кода при написании константных методов.

Это ты ситуации когда надо иметь X& getX() и X& getX() const раздуваешь слона?.. Ответ - зависит от. В этом случае использовать const_cast в неконстантной функции легально, если очень хочется.

М-м-м… ты модифицировал константные объекты?

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

Ну это как бы второй вариант, наоборот, дергать неконстантный метод из константного.

Исправление byko3y, :

Как скажешь. Я просто говорю, что у тех, кто на языке активно пишет. Можешь посмотреть используется ли в каких-нибудь свежих проектах const. По твоей логике, все уже должны были осознать, что это бесполезно, а то и вредно. Или это потому что правильных архитекторов спросить забыли?

Я уже писал по этому поводу, могу пояснить еще раз: использование const вынуждает соседний код использовать const, неиспользование const вынуждает соседний код тоже не использовать const. Тем не менее, повесить const проще, чем его убрать.

Да, извини за «токсичность», но сдержаться сложно

Вообще не почувствовал, слабо стараешься.

Ну нет, такого я не писал. Если переменная mutable (а речь изначально шла об этом), то каст не нужен и соответственно UB тоже нет.
Кстати, даже с кастом это не UB, если объект «на самом деле» не константный

И всё это ты будешь проверять руками, как мой любимый strict aliasing, тоже требующий, чтобы все записи были строго по тому же типу, и тоже компилятор никак не может это проверить.

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

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

Второй симптом одержимости агрегатными объектами мы тоже обсудили — это public/private, которые опять же являются комментариями и возникли из-за того, что в один объект начали совать совершенно разнородные сущности, и в какой-то момент это настолько стало нормой, что уже и не считается проблемой, хотя об эти грабли по прежнему стукаются с завидной регулярностью, когда возникает потребность получить доступ к тому, что автор сторонней либы посчитал недоступным пользователю. Как я уже написал ранее, самый грамотный подход, требующий минимальных телодвижений — это сделать отдельный метод, который вываливает все кишки наружу, «это как бы, ну, на этом наши полномочия всё».

А теперь реши проблему 100500 методов, куда передаётся const MyClass&. Или твоё решение сводится к тому, чтобы никогда и нигде не писать const? Жалко, наверное, что множество кода ему не следуют

Если метод принимает const MyClass& и при этом делает уберсложные операции внутри, которые потенциально даже непрямо изменят значение const MyClass& — то ССЗБ, чо. Как я уже написал, «константно, потому что Мейерс так завещал».

Давай раскроем, зачем нужен const MyClass& arg. Я как-нибудь сам смогу убедиться, что не вызову очевидный arg.x = 1. Потому на самом деле const нужен для того, чтобы я случайно не вызвал неконстантный метод arg. Проблема в том, что если arg является агрегирующим объектом, то этой гарантии мы лишаемся, потому что const методы будут менять объект. Конечно же на самом деле мне нужно не просто const/non-const, а некие более тонкие уровни, вроде «вызов не блокирует объект», «вызов читает значение мимо кэша», которые по класссической крестовой методологии возможно сделать ТОЛЬКО на уровне контрактов и ручной их проверки.

Я предложил выше другой подход — это разобрать агрегаты на отдельные части и гарантировать бинарный const отдельно на блокировке, отдельно на кэше, отдельно на данных. Это прежде всего подразумевает, что ты наконец оторвешь методы-интерфейсы от данных и начнешь ими оперировать отдельно, как это должно быть, если мы наконец перестанем пародировать ООП, которого в C++ на самом деле нет, поскольку инкапсуляция течёт где только можно, а позднего связывания и передачи сообщений никогда не было. Не парадигму языка путать с тем, что написано на самом языке, поскольку написать можно хоть лисп на ассемблере — это не делает асм функциональным языком с GC.

В этом случае использовать const_cast в неконстантной функции легально, если очень хочется. Хотя я думаю, что ты и сам это знаешь, а саму «проблему» подсмотрел у Майерса и пришёл в ужас

Мейерс как раз не видит в этом проблемы, и предлагает именно твое решение. У меня к таким авторам неизменно возникает один и тот же вопрос: они когда-нибудь в своей жизни писали хотя бы одну программу больше пары тысяч строк? Как правило, большинство гуру примерно на этой отметке останавливаются, потому что примерно на таких объемах теряется способность досконально помнить каждую буковку кода и начинается настоящее програмирование. В которое они не умеют, но учат других.

А ты не ответил, что же делать с дублированием кода при написании константных методов.

Это ты ситуации когда надо иметь X& getX() и X& getX() const раздуваешь слона?.. Ответ - зависит от. В этом случае использовать const_cast в неконстантной функции легально, если очень хочется.

М-м-м… ты модифицировал константные объекты?

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

Ну это как бы второй вариант, наоборот, дергать неконстантный метод из константного.

Исходная версия byko3y, :

Как скажешь. Я просто говорю, что у тех, кто на языке активно пишет. Можешь посмотреть используется ли в каких-нибудь свежих проектах const. По твоей логике, все уже должны были осознать, что это бесполезно, а то и вредно. Или это потому что правильных архитекторов спросить забыли?

Я уже писал по этому поводу, могу пояснить еще раз: использование const вынуждает соседний код использовать const, неиспользование const вынуждает соседний код тоже не использовать const. Тем не менее, повесить const проще, чем его убрать.

Да, извини за «токсичность», но сдержаться сложно

Вообще не почувствовал, слабо стараешься.

Ну нет, такого я не писал. Если переменная mutable (а речь изначально шла об этом), то каст не нужен и соответственно UB тоже нет.
Кстати, даже с кастом это не UB, если объект «на самом деле» не константный

И всё это ты будешь проверять руками, как мой любимый strict aliasing, тоже требующий, чтобы все записи были строго по тому же типу, и тоже компилятор никак не может это проверить.

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

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

Второй симптом одержимости агрегатными объектами мы тоже обсудили — это public/private, которые опять же являются комментариями и возникли из-за того, что в один объект начали совать совершенно разнородные сущности, и в какой-то момент это настолько стало нормой, что уже и не считается проблемой, хотя об эти грабли по прежнему стукаются с завидной регулярностью, когда возникает потребность получить доступ к тому, что автор сторонней либы посчитал недоступным пользователю. Как я уже написал ранее, самый грамотный подход, требующий минимальных телодвижений — это сделать отдельный метод, который вываливает все кишки наружу, «это как бы, ну, на этом наши полномочия всё».

А теперь реши проблему 100500 методов, куда передаётся const MyClass&. Или твоё решение сводится к тому, чтобы никогда и нигде не писать const? Жалко, наверное, что множество кода ему не следуют

Если метод принимает const MyClass& и при этом делает уберсложные операции внутри, которые потенциально даже непрямо изменят значение const MyClass& — то ССЗБ, чо. Как я уже написал, «константно, потому что Мейерс так завещал».

Давай раскроем, зачем нужен const MyClass& arg. Я как-нибудь сам смогу убедиться, что не вызову очевидный arg.x = 1. Потому на самом деле const нужен для того, чтобы я случайно не вызвал неконстантный метод arg. Проблема в том, что если arg является агрегирующим объектом, то этой гарантии мы лишаемся, потому что const методы будут менять объект. Конечно же на самом деле мне нужно не просто const/non-const, а некие более тонкие уровни, вроде «вызов не блокирует объект», «вызов читает значение мимо кэша», которые по класссической крестовой методологии возможно сделать ТОЛЬКО на уровне контрактов и ручной их проверки.

Я предложил выше другой подход — это разобрать агрегаты на отдельные части и гарантировать бинарный const отдельно на блокировке, отдельно на кэше, отдельно на данных. Это прежде всего подразумевает, что ты наконец оторвешь методы-интерфейсы от данных и начнешь ими оперировать отдельно, как это должно быть, если мы наконец перестанем пародировать ООП, которого в C++ на самом деле нет, поскольку инкапсуляция течёт где только можно, а позднего связывания и передачи сообщений никогда не было. Не путать с тем, что написано на самом языке, поскольку написать можно хоть лисп на ассемблере — это не делает асм функциональным языком с GC.

В этом случае использовать const_cast в неконстантной функции легально, если очень хочется. Хотя я думаю, что ты и сам это знаешь, а саму «проблему» подсмотрел у Майерса и пришёл в ужас

Мейерс как раз не видит в этом проблемы, и предлагает именно твое решение. У меня к таким авторам неизменно возникает один и тот же вопрос: они когда-нибудь в своей жизни писали хотя бы одну программу больше пары тысяч строк? Как правило, большинство гуру примерно на этой отметке останавливаются, потому что примерно на таких объемах теряется способность досконально помнить каждую буковку кода и начинается настоящее програмирование. В которое они не умеют, но учат других.

А ты не ответил, что же делать с дублированием кода при написании константных методов.

Это ты ситуации когда надо иметь X& getX() и X& getX() const раздуваешь слона?.. Ответ - зависит от. В этом случае использовать const_cast в неконстантной функции легально, если очень хочется.

М-м-м… ты модифицировал константные объекты?

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

Ну это как бы второй вариант, наоборот, дергать неконстантный метод из константного.