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

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

ссылаться на еще не объявленные классы/структуры?
struct A {
B* b;
};
struct B {
A* a;
};
Почему разработчик должен предварительно объявлять структуру для того чтобы ее использовать при объявлении поля? Почему компилятор не может отложить вывод типа пока оно не запарситься (ну или автоматически генерировать struct Name; объявление каждый раз когда встречает поле с неизвестным типом) ?
struct B; //why???
struct A {
B* b;
};
struct B {
A* a;
};

34 ответов

2 просмотра

Кмк очень обскурные ошибки будут. Комилятор компилирует tu, что если в вашем tu B никогда не встретился? И как это фиксить? Куда его инклудить?

Aleksei Kuznetsov Kuznetsov
Кмк очень обскурные ошибки будут. Комилятор компил...

В таком случае можно забить хрен, просто sizeof(void*) бесполезных данных будет занимать

>> почему нельзя при объявлении полей класса ссылаться на еще не объявленные классы/структуры? Чтобы не провоцировать мистические неуловимые ошибки из-за того, что неявно пометили B как тип, а чуть ниже он вдруг стал переменной или шаблоном, или чем-то ещё

Evgeny Sh.
В таком случае можно забить хрен, просто sizeof(vo...

А что если B например вызывает инстанцирование темплейта у которого есть сайдэффекты? Мы тогда все это пропустим

Имхо это наследие строго однопроходной Сишки, где компилятор не мог "вернуться" назад и что-то додумать. В C++ компилятор не однопроходной (те же классы), но наследие тянется

>> Почему разработчик должен предварительно объявлять структуру для того чтобы ее использовать при объявлении поля? Например, потому что это не всегда структура и ваш вопрос перекликается с этим

Ofee Oficsu
>> почему нельзя при объявлении полей класса ссыла...

Как ты сослаться можешь на параметр шаблона/переменную? Т.е. не на тип? B* b; это +- однозначная запись

Богдан- Автор вопроса
Aleksei Kuznetsov Kuznetsov
Кмк очень обскурные ошибки будут. Комилятор компил...

ну вот во время парсинга мы генерируем объявления struct Name; для полей с неизвестными типами и добавляем во временный список а когда запарсили весь translation unit смотрим были ли объявлены типы из этого временного списки и если нет то выдаем ошибку. В чем проблема?

Evgeny Sh.
Как ты сослаться можешь на параметр шаблона/переме...

Это — однозначная. А строкой ниже объявление переменной с тем же именем: B* b; int B; И что у нас получится? А главное, @xbgnx? B — из какого оно скоупа?

Чтобы компилятор понимал, что B - это тип. К тому же, форвард декларация явно указывает, где именно этот тип будет лежать. Могут быть совершенно разные случаи: namespace ns { struct B; } using namespace ns; // vs struct B; Если ещё и A будет лежать в неймспейсе, совсем беда.

Aleksei Kuznetsov Kuznetsov
using B = foo<bar>;

foo<bar> это тип, не параметр шаблона или переменная

Богдан- Автор вопроса
Ofee Oficsu
Это — однозначная. А строкой ниже объявление перем...

из того же скоупа из которого будет предварительное объявление типа перед классом где находится поле с неизвестным типом. То есть я хочу чтобы видя такую запись struct Some { ... SomeType* field; } где SomeType* это неизвестный тип (ранее не встречался) компилятор автоматически вставил бы дополнительную строчку с объявлением этого типа перед текущим классом struct SomeType; //вставленная компилятором строчка struct Some { ... SomeType* field; } и уже в конце парсинга TU компилятор выдал бы ошибку что SomeType это неизвестный тип если он так и не был объявлен Соответственно этот тип будет лежать в этом же скоупе TU (или глобальный неймспейс или как это называется) В чем проблема с таким подходом?

Богдан
из того же скоупа из которого будет предварительно...

using namespace std; namespace A { namespace B { namespace C { namespace { struct Some { ... SomeType* field; }; }}}} В какой из 7(!) скоупов компилятор должен поместить декларацию SomeType?

Богдан
из того же скоупа из которого будет предварительно...

Проблема в том, что вы хотите напрячь писателей компиляторов лишней работой ради неизвестно чего

Богдан- Автор вопроса
Alexander Karaev
Чтобы компилятор понимал, что B - это тип. К тому ...

если у нас есть конфликты имен то выдаем ошибку. Я про кейс когда имя типа поля на момент парсинга неизвестно но будет объявлено позже (то есть берем первое объявление которое встретится позже)

Boris Usievich
Проблема в том, что вы хотите напрячь писателей ко...

Ну я был бы рад не писать тонну forwarding declarations. Если бы компиляторописатели не напрягались, мы бы не увидели auto, концепты, модули...

struct A { struct B* b; } struct B { A* a; }; (и всё)

Зачем нужно то что вы перечислили понятно. А вот зачем ваши хотелки - нет

Чтобы с JS не переучиваться

Не работает если B в неймспейсе

Богдан- Автор вопроса
Alexander Karaev
struct A { struct B* b; } struct B { A* a; };...

Ха, оказыается так можно) Спасибо. Я тогда буду всегда объявлять поля со struct-префиксом и забуду про необходимость предварительно объявлять типы (когда пишешь всякие косвенно-рекурсивные структуры)

Evgeny Sh.
Не работает если B в неймспейсе

Естественно, компилятор не должен в угадайку играть

Богдан
Ха, оказыается так можно) Спасибо. Я тогда буду вс...

>> забуду про необходимость предварительно объявлять типы Рекомендую ещё раз открыть мою ссылку выше и понять, что это тупиковый подход. Декларации всегда должен предоставлять автор класса, и никогда не его пользователь

Dmitriy [Отпуск]
Чтобы с JS не переучиваться

Конечно, кто будет переучиваться с JS на C++, чтобы получать меньшую зарплату

Boris Usievich
Зачем нужно то что вы перечислили понятно. А вот з...

Я же сказал, чтобы не писать тупые forwarding declarations

Evgeny Sh.
Я же сказал, чтобы не писать тупые forwarding decl...

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

Boris Usievich
То есть вам лень написать строчку и вы хотите, что...

Дедам было лень писать for (std::vector<double>::iterator it = v.begin(); it != v.end(); ++it) { ... } но "это другое"?

Evgeny Sh.
Дедам было лень писать for (std::vector<double>::i...

Тут не надо ничего особо делать, тип для auto прямо в этом выражении есть.

Evgeny Sh.
Я же сказал, чтобы не писать тупые forwarding decl...

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

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

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

а зачем этот вопрос для удаления из чата?
Mёdkinson Medvezhkin
62
Всем привет! Подскажите. Я написал приложение на Delphi 10.2 Tokyo под Windows 10. И передо мной стал вопрос о том чтобы сделать это приложение кроссплатформенным (под Linux и...
Дмитрий Завгородний
24
Привет всем. Подскажите где можно посмотреть, какая версия электрон, поддерживает версии windows? Некий changelog. Мне бы желательно, поддержку 7,8,10... latest, как понимаю и...
Anonym Squad
21
Портфолио: Зовут меня Александр, мне 36 лет. Город Пушкино. Общий рабочий стаж: ~14 лет Уровень квалификации: Senior Full-stack developer Где прочесть мой код? https://github....
Magic
10
а где есть mysql cloud кроме яндекс-клауд?
Oleg Nosov
13
Есть ли смысл устраиваться на 1с ? Даст это плюс в дальнейшем трудоустройстве на php? Просто у меня в городе вакансий на пхп нету. Или лучше удаленно искать. Опыта работы нету...
Azamat
13
hi im a cs student. i need some advice from people who have enough experience in Embedded Software. I need to know whether this profession is suitable for me. I have watched s...
Sahand 🏔️
8
use16 org 0x7c00 mov bx, msg call print jmp $ print: pusha start: mov ah, 0x0e mov al, [bx] cmp al, 0 je end ...
sans
4
Кстати а покупал кто-нибудь ЭЦП для подписи кода? А то у меня на некоторых компах и ОС иногда SmartScreen винды программу за вирус принимал. Если купить такую ЭЦП и подписыват...
Дмитрий Завгородний
15
А кто-нибудь запихивал сборку перловых модулей/образов с perl приложениями в окружения без интернета (в специализированном CI/CD)? У меня сейчас есть ряд cpanfile, которые н...
Andrey Smirnov / 𝓪𝓵𝓵𝓽𝓮𝓻 /
14
Карта сайта