170 похожих чатов

Народ, у меня тут теперь вопрос насчет проблемы предварительных объявлений

для косвенно-рекурсивных функций. Если проблема форвард-объявлений для рекурсивных структур решается пусть не автоматически но более удобно через struct/class-префикс у полей то как теперь решить проблему необходимости вручную писать предварительные объявления для косвенно-рекурсивных функций?
auto func(auto n){
if (n == 1) return 1;
return n * func2(n - 1);
};
auto func2(auto n){
if (n == 1) return 1;
return n + func(n - 1);
};
>>clang: call to function 'func2' that is neither visible in the template definition nor found by argument-dependent lookup
Ведь это дико неудобно вручную писать сигнатуру функции, почему компилятор не может автоматически вставить объявление функции если не находит ее имя (и потом в конце парсинга TU поверяем была ли она объявлена и если нет то выдаем ошибку) ?
auto func2(auto arg); // why ???
auto func(auto n){
if (n == 1) return 1;
return n * func2(n - 1);
};
auto func2(auto n){
if (n == 1) return 1;
return n + func(n - 1);
};

34 ответов

24 просмотра

Потому что наследие Си однопроходное

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

Богдан- Автор вопроса
다니엘(줄리아)
Потому что наследие Си однопроходное

Автоматическая генерация предварительных объявлений для неизвестных функций не влияет на однопроходность - я же говорю что компилятор по ходу парсинга может вставлять временные объявления для неизвестных функций и потом в конце парсинга TU посмотреть были эти функции объявлены и если нет то выдать ошибку. Однопроходность по прежнему сохраняется

다니엘(줄리아)
Усложить жизнь всем ради непонятно чего

Ну вообще это не только про "усложнить жизнь" Часто вижу, что код на сях/плюсах пишут снизу вверх, потому как лень дублировать сигнатуру каждой функции. А я вот почему-то привык сверху вниз читать

>> почему компилятор не может автоматически вставить объявление функции если не находит ее имя Потому что это error-prone подход

Ofee Oficsu
>> почему компилятор не может автоматически встави...

Почему, ошибка-то при отсутствии определения ровно такая же будет

Богдан
Автоматическая генерация предварительных объявлени...

>> временные объявления для неизвестных функций С какой сигнатурой?

Sergey Skvortsov
Почему, ошибка-то при отсутствии определения ровно...

Опечатались одной буквой в имени существующей функции и получили ошибку на этапе линковки? Красиво...

Богдан- Автор вопроса
Ofee Oficsu
>> временные объявления для неизвестных функций С...

auto name (auto arg1, auto arg2, ...) где число параметров будет равно числу аргументов при вызове неизвестной функции

Богдан
auto name (auto arg1, auto arg2, ...) где число па...

А ничего, что auto name(auto arg); является декларацией совершенно другой перегрузки, нежели ожидает пользователь?

Ofee Oficsu
А ничего, что auto name(auto arg); является декла...

А какую декларацию вы вставите для такого вызова? foo(1, 2, {3, 4, 5}, 42);

Богдан- Автор вопроса
Ofee Oficsu
А ничего, что auto name(auto arg); является декла...

Это же только временно при парсинге TU пока не встретится определение самой функции, как только встретилось то это временное объявление удаляем. Как оно может повлиять на какие-либо перезагрузки если это временное объявление учавствовать в перезагрузках не будет?

Богдан
auto name (auto arg1, auto arg2, ...) где число па...

Это не так должно работать Первым проходом собираются все объявления и определения функций, на втором проходе обычный name lookup. Проблема в том, что это опять ломающее изменение, и в плюсах не появится.

Богдан
Это же только временно при парсинге TU пока не вст...

>> пока не встретится определение самой функции, Как понять, что определение пользовательской функции совпадает со сгенерированной?

Sergey Skvortsov
Это не так должно работать Первым проходом собираю...

и такой подход реально ухудшит ситуацию с перегрузками

Богдан
Это же только временно при парсинге TU пока не вст...

void f(double) {} void g(int i) { f(i); } void f(int) {} Предлагаю подумать над этим примером

Kelbon
и такой подход реально ухудшит ситуацию с перегруз...

С чем вы спорите-то?) Я вроде явно написал, что в C++ мы этой фичи не увидим, по крайней мере, до механизма вроде эпох.

Sergey Skvortsov
С чем вы спорите-то?) Я вроде явно написал, что в ...

вопрос не в том увидим или нет, а в том заачееем

А теперь представьте, что пользователь хотел, но забыл объявить f от double. Теперь вместо заблаговременной ошибки, он получит неожиданное поведение. Почти наверняка рантайм баг

Богдан- Автор вопроса
Ofee Oficsu
А теперь представьте, что пользователь хотел, но з...

Ну да, компилятор выберет функцию которая объявлена ниже потому что в файле больше нет никакого упомнания о другой перезагрузки функции (соотвественно никакие правила overloading и name-lookup нарушаться не будут) Аргумент "хотел но забыл" мне непонятен - если не объявить f(double) то компилятор сейчас выдает ошибку и логичнее было бы выбрать функцию которая объявлена ниже чтобы получить работающий код потому что сейчас согласно философии С++ считает что программист пишет код без ошибок и поэтому компиляторы вместо того чтобы проверять код на UB (и только потом уже оптимизировать) сразу бегут оптимизировать считая что UB нет что может приводить к удивительным багам (https://t.me/ProCxx/504005)

Богдан
Ну да, компилятор выберет функцию которая объявлен...

Вот именно. Сейчас будет ошибка, а вы предлагаете замести мусор под ковер

>> то компилятор сейчас выдает Именно, это ожидаемое поведение. А если не выдать ошибку, а вместо этого начать выбирать среди двух перегрузок ниже – пользователь не этого ожидал Кроме того, забытые инклуды начнут генерировать ещё более весёлые баги со сборкой проекта >> согласно философии С++ считает что программист пишет код без ошибок Боюсь, философия несколько сложнее и вы неверно её поняли. UB перекладывает ответственность на программиста... с благородной целью – обеспечить возможности оптимизации. Вы же предлагаете ради сиюминутного синтаксического сахара повысить риск отстрела ног, а так же затруднить непродуманной идеей будущее развитие языка Может, вам стоит написать собственный язык, чтобы понять процесс дизайна?

Богдан- Автор вопроса
Boris Usievich
Вот именно. Сейчас будет ошибка, а вы предлагаете ...

Я предлагаю не накидывать на программиста тупую работу которую может сделать компилятор, необходимость вручную предварительно объявлять сигнатуру функции (когда она же объявляется чуть ниже в этом же файле) это чистой воды болерплейт который не несет никакой информации и только раздувает код

Богдан
Я предлагаю не накидывать на программиста тупую ра...

А вы пробовали Rust? С таким бэкграундом и запросами явно лучше пойдет, без шуток.

Богдан- Автор вопроса
Ofee Oficsu
>> то компилятор сейчас выдает Именно, это ожидае...

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

Богдан
Я предлагаю не накидывать на программиста тупую ра...

сигнатуры функций и объявления классов - отличная фича С/С++, существенно облегчающая навигацию по коду, его понимание, и в целом поддерживаемость

Богдан
Прочитайте внимательно то мое сообщение, я там по ...

Вы же понимаете, что комитет наоборот предпринимал меры, минимизирующие влияние последующего кода?

Alexander Karaev
void f(double) {} void g(int i) { f(i); } void...

Вот сюда ещё дописать слово inline в объявления inline void f(double) {} inline void g(int i) { f(i); } void f(int) {}

Constantine Drozdov
Вот сюда ещё дописать слово inline в объявления i...

Теперь нарушен ODR, никакие/некоторые TU после линковки несут ошибочный код, удачной отладки

Богдан- Автор вопроса
Sergey Skvortsov
А вы пробовали Rust? С таким бэкграундом и запроса...

Я пробовал разные языки за 9 лет разработки. Я даже несколько месяцев в фулл-тайм режиме писал свой язык и я конечно хотел бы писать на нем но это потом когда я перестану искать работу по найму и смогу заниматься своими стартапами. А пока мне нужен популярный язык (чтобы на нем можно было бы найти работу) и к плюсам я сейчас пришел сознательно (после 7 лет JS/TS веб-разработки) потому что 1) С/С++ это один из самых популярных языков и развитых экосистем и уступает разве что только JS по количеству вакансий (и тот же Rust здесь в подметки не годится) 2) С++ мне нравится тем что это очень гибкий язык по сути конструктор из которого я могу слепить язык под свои вкусы чтобы писать на плюсах код так как я привык на другом языке (или точнее с теми же удобствами). Раст в этом плане намного менее гибкий и там много чего форсируется

Похожие вопросы

Обсуждают сегодня

Ребят в СИ можно реализовать ООП?
Николай
33
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Добрый вечер, Пока не совсем понимаю как наладить общение между телеграм ботом и ПО для работы с сим боксом. По самому боту так понял: - Нужен некий баланс, который можно поп...
Magic
6
Всем доброго вечера. Разрабатываю 32 раз. приложение в Delphi. Столкнулся с тем, что стандартный  TFilestream  не работает с большим файлом > 2 ГБайт (после вызова функции see...
Vadim Gl
16
Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
добрый день. Подскажите, есть сайт на 1.4.7 и я хочу обновиться, особо ничего не меняя. мне выбирать версию 1.4.35 или третью ветку? и можно ли обновлять "как есть", или нужно...
Digital Cat
12
Кто кодит под Лазарем на винде, у вас аналогично VCL переопределяются CreateWnd и CreateParams для конкретных классов контролов и все заданные флаги влияют?
А Андрей
11
У меня задача: написать брокер сообщений. Очереди и потребители. Очереди поддерживают приоритеты. Очередь отдает сообщения, только обработчикам с соответствующими характеристи...
Aleksandr Filippov
2
народ, плиз хелп, всю голову сломал себе уже... разве может быть так, что GetProcAddress( GetModuleHandle( "kernel32.dll" ), "SetThreadDescription" ) вернёт ненулевое значение...
Iluha Companets
12
А, ты про текущую реализацию? Нет конечно, я бы сделал правильно - сейчас там гавнокод
Александр (Rouse_) Багель
6
Карта сайта