которое занимает переменная и ее тип. Почему я не могу сказать укзателю, что теперь по этому адресу int, а не double?
Потому что это нарушение strict aliasing
Потому что изначально вы положили в коробку котенка, а теперь говорите компилятору, что там сидит щенок) Вот компилятор и ругается
Компилятор бы не ругался, не будь это каст с проверкой. Но даже без проверки это UB
Ну, про реинтерпрет я упомянул чуть выше)
А вот если я то же самое оберну в класс и сделаю dynamic_cast, то это сработает?
dynamic_cast только для кастов вверх/вниз по иерархии
dynamic_cast имеет не то предназначение. Он имеет предназначение перемещения по полиморфной иерархии. Если в базовом класе будет инт, например, а в наследнике будет поле с даблом, ну и это будут полиморфные классы, то сработает
Бывают ещё side касты и кросс касты
Стопстопстоп, не путайте теплое с мягким. Во-первых, динамик каст тоже каст с проверкой. Только проверка в рантайме. А статик каст проверяет на этапе компиляции. Во-вторых, он используется, в основном, для преобразования от родителя к наследнику (или наоборот, но там и статик так-то работает)
ТО есть изменить тип указателя с int на double я не могу, но если я оберну обе переменных в классы и унаследую один класс от другого, то никаких проблем... Логичный подход. не придерешься.
Легче загуглить, я тут не нарисую. Но к примеру, у класса два интерфейса, а мы из левого кастуем в правый
Множественное наследование?
Да, и в классе наследнике будет поле с указателем на инт и с указателем на дабл
Это уже надо самописные касты, нет? Динамик не даст так сделать?
Даст, это легально
Брократия в программировании!
А если у нее коробка с дырявым дном и она котенка на щенка поменяла?
Что-то вроде такого? struct C : A, B {} A * a = new C(); B * b = dynamic_cast<B*>(a);
Интересно, спасибо, не задумывался об этом никогда
Либо очень тонкий расчет
Погодите, если я в наследнике сделаю оверрайд функции или переменной, то там будет зарезервировано место для переменной из базового класса тоже?
Оверрайд переменной сделать нельзя. И да, в наследнике будет содержаться база
Потому что в памяти С++ лежат объекты, а не байты
Хорошо. Скажите, если я создаю int array традиционным способом: int array[5] = {1, 2, 3, 4, 5}; и создаю его же с помощью оператора new int* array = new int[5]{1, 2, 3,4 ,5}; это одинаковые по структуре объекты?
Нужно различать объект от его хранилища. Объекты одинаковые, да. При этом storage duration в одном случае автоматический, в другом динамический
отлично. Теперь я передаю первый array в функцию. void myfunction(int array[]) {} myfunction(array) то почему в функцию приходит только указатель на первый элемент? Где остальное?
Потому что массив - это указатель на первый элемент.
А вот это уже сишное наследие. С точки зрения языка си, запись int array[] в аргументе функции означает передачу "по указателю", а передачи массива по значению в си нет. Если вместо этого вы будете использовать std::array<int, 5>, массив будет скопирован
Не совсем так, он decay'ит к указателю
Из языка Си в С++ есть особые случаи, связанные с типами в аргументах и возвращаемых значениях функции
Хорошо, но почему тогда в случае статического массива я могу итерировать по элементам не боясь выйти за пределы массива for(int aNumber : array) а при указателе на массив мне нужно отдельно таскать еще и размер массива? Как такое может быть если это одинаковые объекты?
Ок :3 пните, как можно возвращаться :3
Окей. В каких случаях массив не может скаститься до указателя на 1-й элемент массива?
В первом случае вы работаете с объектом типа массив, во втором - с указателем на элемент
Мы проводим статопрос перед умерщвлением плоти. Кто эту дичь вам сказал про указатель?
При этом вы можете сделать статический массив, привести его к указателю и потерять эту возможность
Да никто не сказал. Щас, уно моментум
Хорошо, то есть получается что статический массив и массив в куче — это разные объекты?
Потому что это не указатель на массив
Вопрос не ко мне, но я тоже, пожалуй, отвечу. Собственные наблюдения, в том числе с использованием отладчика, и изучение дизассеблерного кода. Вы же, попав молотком по пальцам, тоже делаете вывод, что это больно? При этом совсем не требуется, чтобы вам об этом рассказал кто-то ещё.
Попробуйте представить себе, что такое "улица Пушкина" и чем она отличается от "улица Пушкина, дом 0" как адрес
У них разный storage duration, об этом уже сказали. В случае динамического выделения у вас просто нет выбора кроме как обращаться к массиву по указателю
"улица Пушкина, дом 0"[5] это дом "улица Пушкина, дом 5" "улица Пушкина"[5] это дом "улица Пушкина, дом 5" это не значит, что адрес дома 0 по улице Пушкина и улица Пушкина одно и то же
Чуви, ты наркоман
улица Пушкина это вообще два адреса дома, первого и последнего
А с ним согласен. Массивы выглядят как указатели внутри функций. Аллоцированные на стеке через alloca
Они не выглядят, они низводятся до указателей
Нет, ну вот в LLVM IR, к примеру, массивы не являются SSA-value, они являются указателями
низводятся это стандартный перевод для decay?
Кажется стандартный это "деградируют"
Обсуждают сегодня