cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

Запретить писать inline для constexpr-функций и переменных #500

Closed Izaron closed 2 years ago

Izaron commented 2 years ago

constexpr- и consteval-методы и constexpr-переменные неявно объявлены inline [dcl.constexpr]

Это логично - если у них есть шанс вычислиться в compile-time, то им можно немного обойти ODR. Потому что вычислить метод, не видя его определения в текущем translation unit, невозможно by desing.

Однако многие программисты, наверное, либо не знают это, либо добавляют inline "для надежности". В результате вагон проектов самой разной крутости имеют кучу inline constexpr/inline consteval https://github.com/search?p=1&q=inline+constexpr&type=Code (clang и gcc не выводят warning на это, всем пофигу)

Есть возможность "упростить" язык, одновременно повышая "грамотность" программистов, выводя ошибку о том, что метод уже является inline.

UPD: inline constexpr-переменные смысл всё же имеют. А методы и static data members - нет.

kelbon commented 2 years ago

сделать ошибкой то, что не является ошибкой и сломать код, который не является ошибочным? Зачем, можно просто варнинг ввести, да и то не факт что он нужен(раз до сих пор нет)

pavelkryukov commented 2 years ago

clang и gcc не выводят warning на это, всем пофигу

В Clang-Tidy есть заброшенная имплементация: https://reviews.llvm.org/D18914

Gargony commented 2 years ago

сделать ошибкой то, что не является ошибкой и сломать код, который не является ошибочным? Зачем, можно просто варнинг ввести, да и то не факт что он нужен(раз до сих пор нет)

но const на статическом методе даёт ошибку, хотя мы точно не модифицируем объект

kelbon commented 2 years ago

сделать ошибкой то, что не является ошибкой и сломать код, который не является ошибочным? Зачем, можно просто варнинг ввести, да и то не факт что он нужен(раз до сих пор нет)

но const на статическом методе даёт ошибку, хотя мы точно не модифицируем объект

конечно это ошибка, ведь это эквивалентно const на неявном первом аргументе - указателе this, а его у статического метода нет

pavelkryukov commented 2 years ago

но const на статическом методе даёт ошибку, хотя мы точно не модифицируем объект

Там ошибка в том, что свойство константности применяется к несуществующему в этом контексте this.

Izaron commented 2 years ago

fun fact - стандарт не запрещает писать подобное (правда, warning будет):

inline inline inline inline inline inline inline constexpr int sum(int n) {
    int res = 0;
    for (int i = 1; i <= n; ++i)
        res += i;
    return res;
}
pavelkryukov commented 2 years ago

Кстати, в результатах поиска, на которые вы сослались, довольно много конструкций условной компиляции вроде CONSTEXPR_IF_2011 inline foo(). Если запретить inline constexpr, придётся реализовывать условную компиляцию куда сложнее.

Izaron commented 2 years ago

Я поисследовал другие спецификаторы, и понял, что максимум, на что можно рассчитывать это Warning компилятора, потому что, например дублирующиеся спецификаторы не являются ошибкой компиляции

Возможно, примут этот патч - https://reviews.llvm.org/D117435

В Clang-Tidy есть заброшенная имплементация: https://reviews.llvm.org/D18914

Спасибо! Если интересно знать - аргумент против этого патча (атрибут inlinehint в LLVM IR у inline метода) уже не работает, потому что этот атрибут перестали ставить начиная с Clang 3.3 (обнаружил через godbolt).

pavelkryukov commented 2 years ago

аргумент против этого патча (атрибут inlinehint в LLVM IR у inline метода) уже не работает

а аргумент и тогда не работал, разумно было бы хинт и для constexpr генерировать