LINUX.ORG.RU

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

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

Он это может в одном случае написать, а в другом нет.

Проблема в том, что как я уже не первый и даже не десятый раз пишу, в C и C++ (во всяком случае, до появления C++20) вместо отсутствующей в этих языках модульности применяются костыли на директивах препроцессора. Сам по себе препроцессор весьма мощная и полезная штука, но его применение для затыкания им отсутствия модулей в языке тащит за собой несколько застарелых болячек.

Самая, имхо, коварная из этих болячек состоит в том, что #include транзитивен. Если наш модуль файл исходника не инклудит напрямую заголовочник, в котором описан требуемый класс, но инклудит другой заголовочник, в котором по счастливому совпадению инклудится нужный — с точки зрения компилятора это совершенно нормально. Даже если требуемое находится через цепочку из десятка инклудов.

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

Звучит как экзотика, но в реальности я на такое поведение натыкался неоднократно, особенно в чужом коде. В своём в итоге выработал привычку: пишешь какой-нибудь библиотечный тип или вызов функции — сразу проверяю, есть ли у меня наверху нужный #include. Именно в том же файле, где этот тип/функция нужен, а не «где-то там за горизонтом».

Вот к примеру, в Delphi/fpc uses нетранзитивен. В хорошем смысле. :) Там, если я что-то нужное не указал, я гарантированно получу ошибку. В import из Java, ЕМНИП, тоже. Как сделано в модулях С++20 — не знаю, давно хочу потыкать, но пока не добрался.

Соответственно, мне интересно, как сделано в предлагаемой утилите. Если она просто раскручивает простыни текста, как компилятор с препроцессором — в принципе, полезно, но не так интересно: «проклятие транзитивности» никуда не уходит. А вот если она способна предсказывать такого рода косяки — то ей цены нет.

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

Он это может в одном случае написать, а в другом нет.

Проблема в том, что как я уже не первый и даже не десятый раз пишу, в C и C++ (во всяком случае, до появления C++20) вместо отсутствующей в этих языках модульности применяются костыли на директивах препроцессора. Сам по себе препроцессор весьма мощная и полезная штука, но его применение для затыкания им отсутствия модулей в языке тащит за собой несколько застарелых болячек.

Самая, имхо, коварная из этих болячек, состоит в том, что #include транзитивен. Если наш модуль файл исходника не инклудит напрямую заголовочник, в котором описан требуемый класс, но инклудит другой заголовочник, в котором по счастливому совпадению инклудится нужный — с точки зрения компилятора это совершенно нормально. Даже если требуемое находится через цепочку из десятка инклудов.

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

Звучит как экзотика, но в реальности я на такое поведение натыкался неоднократно, особенно в чужом коде. В своём в итоге выработал привычку: пишешь какой-нибудь библиотечный тип или вызов функции — сразу проверяю, есть ли у меня наверху нужный #include. Именно в том же файле, где этот тип/функция нужен, а не «где-то там за горизонтом».

Вот к примеру, в Delphi/fpc uses нетранзитивен. В хорошем смысле. :) Там, если я что-то нужное не указал, я гарантированно получу ошибку. В import из Java, ЕМНИП, тоже. Как сделано в модулях С++20 — не знаю, давно хочу потыкать, но пока не добрался.

Соответственно, мне интересно, как сделано в предлагаемой утилите. Если она просто раскручивает простыни текста, как компилятор с препроцессором — в принципе, полезно, но не так интересно: «проклятие транзитивности» никуда не уходит. А вот если она способна предсказывать такого рода косяки — то ей цены нет.

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

Он это может в одном случае написать, а в другом нет.

Проблема в том, что как я уже не первый и даже не десятый раз пишу, в C и C++ (во всяком случае, до появления C++20) вместо отсутствующей в этих языках модульности применяются костыли на директивах препроцессора. Сам по себе препроцессор весьма мощная и полезная штука, но его применение для затыкания им отсутствия модулей в языке тащит за собой несколько застарелых болячек.

Самая, имхо, коварная из этих болячек, состоит в том, что #include транзитивен. Если наш модуль файл исходника не инклудит напрямую заголовочник, в котором описан требуемый класс, но инклудит другой заголовочник, в котором по счастливому совпадению инклудится нужный — с точки зрения компилятора это совершенно нормально. Даже если требуемое находится через цепочку из десятка инклудов.

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

Звучит как экзотика, но в реальности я на такое поведение натыкался неоднократно, особенно в чужом коде. В своём в итоге выработал привычку: пишешь какой-нибудь библиотечный тип или вызов функции — сразу проверяю, есть ли у меня наверху нужный #include. Именно в том же файле, где этот тип/функция нужен, а не «где-то там за горизонтом».

Вот к примеру, в Delphi/fpc uses нетранзитивен. Там, если я что-то нужное не указал, я гарантированно получу ошибку. В import из Java, ЕМНИП, тоже. Как сделано в модулях С++20 — не знаю, давно хочу потыкать, но пока не добрался.

Соответственно, мне интересно, как сделано в предлагаемой утилите. Если она просто раскручивает простыни текста, как компилятор с препроцессором — в принципе, полезно, но не так интересно: «проклятие транзитивности» никуда не уходит. А вот если она способна предсказывать такого рода косяки — то ей цены нет.

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

Он это может в одном случае написать, а в другом нет.

Проблема в том, что как я уже не первый и даже не десятый раз пишу, в C и C++ (во всяком случае, до появления C++20) вместо отсутствующей в этих языках модульности применяются костыли на директивах препроцессора. Сам по себе препроцессор весьма мощная и полезная штука, но его применение для затыкания им отсутствия модулей в языке тащит за собой несколько застарелых болячек.

Самая, имхо, коварная из этих болячек, состоит в том, что #include транзитивен. Если наш модуль файл исходника не инклудит напрямую заголовочник, в котором описан требуемый класс, но инклудит другой заголовочник, в котором по счастливому совпадению инклудится нужный — с точки зрения компилятора это совершенно нормально. Даже если требуемое находится через цепочку из десятка инклудов.

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

Звучит как экзотика, но в реальности я на такое поведение натыкался неоднократно, особенно в чужом коде. В своём в итоге выработал привычку: пишешь какой-нибудь библиотечный тип или вызов функции — сразу проверяю, есть ли у меня наверху нужный #include.

Вот к примеру, в Delphi/fpc uses нетранзитивен. Там, если я что-то нужное не указал, я гарантированно получу ошибку. В import из Java, ЕМНИП, тоже. Как сделано в модулях С++20 — не знаю, давно хочу потыкать, но пока не добрался.

Соответственно, мне интересно, как сделано в предлагаемой утилите. Если она просто раскручивает простыни текста, как компилятор с препроцессором — в принципе, полезно, но не так интересно: «проклятие транзитивности» никуда не уходит. А вот если она способна предсказывать такого рода косяки — то ей цены нет.