Здравствуйте, Dair, Вы писали:
D>Коллеги,
D>Есть ли смысл в подобном коде:
D>[/ccode]
D>Или это яркий пример так называемого говнокода, как мне и показалось с первого взгляда?
Это Undefined Behavior со всеми вытекающими. Но от лени его пишут — например, когда у SomeClass есть методы, не требующие this для работы или когда нет контроля над интерфейсом а NULL вернуть надо
Но всё равно UB
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, jazzer, Вы писали:
D>>>Есть ли смысл в подобном коде J>>с С++11 — нет, так как для этого в Стандарте есть std::declval<const SomeClass>()
EP>declval для случая ТС не подходит, у него другой контекст.
Ну он же не показал, как оно используется. У меня такая конструкция была только в местах, где сейчас надо использовать declval.
Хотя вру, еще она у меня использовалась, чтобы узнать смещение члена класса в объекте. Но сейчас offsetof тоже есть в Стандарте (правда там куча оговорок).
Здравствуйте, jazzer, Вы писали:
J>Ну он же не показал, как оно используется.
Тем не менее, если в том коде использовать declval — то программа не соберётся.
J>У меня такая конструкция была только в местах, где сейчас надо использовать declval.
Это да.
J>Но сейчас offsetof тоже есть в Стандарте (правда там куча оговорок).
offsetof есть начиная с C++98, а пришёл он ЕМНИП из C.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, jazzer, Вы писали:
J>>Ну он же не показал, как оно используется.
EP>Тем не менее, если в том коде использовать declval — то программа не соберётся.
В каком "в том"? там же нету кода, там есть функция, которая заменяется (с упомянутыми оговорками) на declval...
J>>Но сейчас offsetof тоже есть в Стандарте (правда там куча оговорок).
EP>offsetof есть начиная с C++98, а пришёл он ЕМНИП из C.
но он только для standard layout и всякое такое, там куча ограничений. А хак с нулевым указателем будет работать везде (и на древних компиляторах тоже)
Здравствуйте, jazzer, Вы писали:
J>>>Ну он же не показал, как оно используется. EP>>Тем не менее, если в том коде использовать declval — то программа не соберётся. J>В каком "в том"? там же нету кода, там есть функция, которая заменяется (с упомянутыми оговорками) на declval...
А, ты о том чтобы заменить весь метод declval'ом. В таком случае, если там действительно declval был бы уместен то и тело метода в изначальном варианте было бы не нужно (достаточно было бы декларации) — но это уже всё размышление на тему "что хотел сказать автор".
Здравствуйте, MT-Wizard, Вы писали:
MW>или когда нет контроля над интерфейсом а NULL вернуть надо
Главное потом аккуратно это всё использовать, ибо UB. Некоторое время назад ловил баг в сторонней библиотеке связанный как раз с этим — в ссылках передавался nullptr, и в одном из мест был тест ссылки на этот самый nullptr, который компилятор безусловно выкидывал пользуясь правом UB, и код ниже соответственно падал понадеявшись на проверку.
Здравствуйте, Dair, Вы писали:
D>Или это яркий пример так называемого говнокода, как мне и показалось с первого взгляда?
Без контекста непонятно, до какой степени это говнокод.
Но говнокод в любом случае, т.к. это эксплуатация неопределённого поведения.
Перечень бомб, которые здесь заложены:
— оптимизатор может бодро повыкидывать куски рабочего кода
— AV, если вдруг потребуется разыменовать указатель, — например, какая-то функция из невиртуальной будет переделана в виртуальную, или если оптимизатор заменит статический вызов виртуальной функции на динамический
— ненулевой адрес базы/наследника при сдвиге базы (при работе с указателями создаётся специальный код, превращающий нуль в нуль; при работе со ссылками этих проверок нет)
— последующее AV при работе с ненулевыми же адресами!
— в параноидном режиме программа просто не скомпилируется
Здравствуйте, Кодт, Вы писали:
К>Без контекста непонятно, до какой степени это говнокод.
Контекста я не застал, потому что [см.ниже]
Посмотрел по коду немного — это заглушка виртуальной функции.
К>- в параноидном режиме программа просто не скомпилируется
есть у нас либА, которая делается в соседнем отделе. Эта либа перестала собираться с обновлением Xcode (и clang, видимо), именно на вот этом месте.
Коллеги переделали функцию, теперь она возвращает указатель, а не константную ссылку.
Здравствуйте, Dair, Вы писали:
К>>- в параноидном режиме программа просто не скомпилируется D>есть у нас либА, которая делается в соседнем отделе. Эта либа перестала собираться с обновлением Xcode (и clang, видимо), именно на вот этом месте.
Вот за это я люблю шланг! Хотя, местами, он параноит больше, чем надо. Но эта паранойя регулируется.
D>Коллеги переделали функцию, теперь она возвращает указатель, а не константную ссылку.
Ага, и перенесли эпицентр взрыва с места пуска в место попадания. Ма-лай-цы.
Срочно скажи им, чтобы засунули в заглушку ассерт. И/или написали в документации, что виртуальная функция может возвращать нуль.
Здравствуйте, Кодт, Вы писали:
К>Срочно скажи им, чтобы засунули в заглушку ассерт. И/или написали в документации, что виртуальная функция может возвращать нуль.
А вот просто написать virtual someFunction() == 0, не?
D>>Или это яркий пример так называемого говнокода, как мне и показалось с первого взгляда?
MZ>Это -- яркий пример говнокода. MZ>И мне стыдно, но я когда-то такой код писал сам
MZ>НАДО КИДАТЬ ИСКЛЮЧЕНИЕ!
Нет, не надо Исключение надо бросать тогда, когда ошибку невозможно исправить после внимательного прочтения кода. То есть, когда ошибка вызвана какими-то внешними факторами. Здесь же будет достаточно ассерта или что-то в этом роде.
MNZ:
MZ>>НАДО КИДАТЬ ИСКЛЮЧЕНИЕ!
MNZ>Нет, не надо Исключение надо бросать тогда, когда ошибку невозможно исправить после внимательного прочтения кода. То есть, когда ошибка вызвана какими-то внешними факторами. Здесь же будет достаточно ассерта или что-то в этом роде.
Здравствуйте, Кодт, Вы писали:
К>- ненулевой адрес базы/наследника при сдвиге базы (при работе с указателями создаётся специальный код, превращающий нуль в нуль; при работе со ссылками этих проверок нет)
Вроде как и для ссылок есть проверки. Правда, говорят, не во всех случаях