LINUX.ORG.RU

Целочисленный. Указатель это значение, а не сущность отдельная. А так, такой какой у тебя в исходниках задекларирован или тот к которому ты его скастовал (тоесть каст означает смену типа обработки данных коими и является указатель)

anonymous
()
Ответ на: комментарий от blexey

в рантайм типов нет. Например m - вычисляется и равно 10.

Как правильно вычислить (ptr+m) смещение?

LZai
() автор топика
Ответ на: комментарий от LZai

Как правильно вычислить (ptr+m) смещение?

В базовой документации к языку это описано. Поди да почитай.

anonymous
()
Ответ на: комментарий от LZai

Причём тут рантайм? Ты в исходниках типы от балды пишешь? man sizeof

anonymous
()
Ответ на: комментарий от LZai

в рантайм типов нет.

факт, нет

Например m - вычисляется и равно 10. Как правильно вычислить (ptr+m) смещение?

на этапе компиляции известно sizeof(*ptr). вот на этапе компиляции, тебе компилятор заменит (ptr+m) на (raw_ptr + m*sizeof(*ptr))

Sectoid ★★★★★
()
Ответ на: комментарий от Sectoid

Ладно. Это понятно.

Теперь void* ptr. ptr - адрес, для простоты равен 1.

чему равно ptr+10? 11? а почему не 111?

LZai
() автор топика
Ответ на: комментарий от LZai

А для чего тогда сделали приведение типов (void*)?

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

тут снова внутренняя ванга говорит, что вроде бы как раз для void* единственная определенная операция это каст обратно к тому T*, из которого он был сделан. но тут могу и ошибаться, цитату привести не готов.

Sectoid ★★★★★
()
Ответ на: комментарий от LZai

Т.е. ((T*)((void*) ptr)) + 10 сместит указатель в нужное место?

не уверен на 100% какое именно место ты считаешь нужным, но внутренняя ванга говорит, что да :)

Sectoid ★★★★★
()
Ответ на: комментарий от fsb4000

Бьярне Строуструп говорит, чтобы ты не пользовалась адресной арифметикой, и он просил тебе это лично передать:

… и ООП, так его по пьянке на спор разработал.

anonymous
()

й…ный ты по голове. Почитай ты книгу из серии «С++ для чайников»

anonymous
()
Ответ на: комментарий от LZai

куда передать? кому передать? по сети передать? в функция передать?

anonymous
()
Ответ на: комментарий от LZai

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

gremlin_the_red ★★★★★
()
Ответ на: комментарий от LZai

Что конкретно нужно передать?

Ну и передавай матрицу, по ссылке. Или экземпляр собственного класса матрица.

fsb4000 ★★★★★
()
Ответ на: комментарий от LZai

А как эффективно передать матрицу NxMxKxL причем там разные типы объектов?

Если объекты в матрице разные и при этом «маленькие», то хранить одномерный массив n*m*k*l значений типа union. Точнее что там сейчас в std вместо юнион. Одномерный — чтобы было в одном куске. При работе кастуешь к четырёхмерному.

Есди объекты в матрице «большие», то всё то же самое, только хранятся указатели.

Crocodoom ★★★★★
()
Ответ на: комментарий от fsb4000

Матрица - набор типов. Например комплексные числа - координаты, интервалы - время и т.д. Передается в функцию как void*.

LZai
() автор топика
Ответ на: комментарий от Crocodoom

Ну я примерно поняла как делать. Если строка std::complex, то приводишь void* к указателю на этот тип, а дальше компилятор сам вычислит нужное смещения при добавлении целого индекса.

LZai
() автор топика
Ответ на: комментарий от LZai

Передается в функцию как void*.

Зачем? В С++ как минимум есть std::any, который кинет исключение если ты передашь что-то не то, что ожидает функция.

А так есть шаблоны чтобы не терять информацию о типе. Хотя если тебе нужно стирать типы по каким-то причинам, то тогда std::any.

void* это С, не С++…

fsb4000 ★★★★★
()

Указатель по posix не имеет типа ибо должен уметь содержать какие угодно данные (data pointer)

golovastik
()
Ответ на: комментарий от LZai

Как правильно вычислить (ptr+m) смещение?

Величина на которую будет увеличен адрес памяти при прибавлении 1 рассчитывается на этапе компиляции исходя их типа на который указывает ptr.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 1)
Ответ на: комментарий от LZai

А для чего тогда сделали приведение типов (void*)?

Для того, чтобы можно было передавать указатель на объект любого типа.

rumgot ★★★★★
()

Указатели не нужны. Как и говноязыки, в которых они присутствуют.

anonymous
()
Ответ на: комментарий от Crocodoom

Если уж есть желание экономить на подобных спичках, нужно аллоцировать N* sizeof(T1) * M * sizeof(T2) * ... байт памяти и оффсеты считать. Юнион по размеру будет равен размеру наибольшего типа внутри, поэтому оверхед по памяти от матрицы юнионов может быть очень большим.

Везде в этом сообщении, где пишу «юнион», можно читать как union, так и variant.

Siborgium ★★★★★
()
Ответ на: комментарий от anonymous

Целочисленный. Указатель это значение, а не сущность отдельная.

Лол нет. В стандарте написано, что указатель должен кастоваться к инту и обратно. Но внутреннее представление может быть любым.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

В стандарте написано, что указатель должен кастоваться к инту и обратно

В стандарте такого не может быть написано, хотя бы потому что int и указатель могут быть разных размеров.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

В стандарте такого не может быть написано

Да, там чуток не так.

Вот цитата из стандарта:

A pointer can be explicitly converted to any integral type large enough to hold all values of its type. The mapping function is implementation-defined

fsb4000 ★★★★★
()

Это ведь просто адрес памяти. Откуда известно на что он указывает на int или obj A?

От программиста.

anonymous
()

А ещё бывает тегированная память, тот же Эльбрус

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

(цитата про советский эльбрус)

Crocodoom ★★★★★
()
Последнее исправление: Crocodoom (всего исправлений: 1)
Ответ на: комментарий от Crocodoom

Развитая система тегов допускала динамическую типизацию.

А почему в прошедшем времени?

anonymous
()
Ответ на: комментарий от anonymous
Empty your memory,
with a free()...
like a pointer!

If you cast a pointer to a integer,
it becomes the integer.
If you cast a pointer to a struct,
it becomes the struct...

The pointer can crash..,
and can Overflow...

Be a pointer my friend...
beastie ★★★★★
()
Ответ на: комментарий от beastie

Be a pointer my friend…

«Всегда быть в маске - его судьба» /и про к-ус также/.

anonymous
()
Ответ на: комментарий от anonymous

В советских было 8 разрядов на тег (256 тегов), а в новых только 2 разряда (4 тега): типизация не помещается.

Crocodoom ★★★★★
()
Ответ на: комментарий от Crocodoom

…, а в новых только 2 разряда (4 тега): типизация не помещается.

И для чего тогда они используются?

anonymous
()
Ответ на: комментарий от anonymous

Целочисленный

Знаковый?

каст означает смену типа

Чо там насчёт кастануть в уинт64_т на 32 битах?

deep-purple ★★★★★
()
Ответ на: комментарий от fsb4000

Бьярне Строуструп говорит, чтобы ты не пользовалась адресной арифметикой

Труп страуса должен был сказать иначе. А именно: пользуйся, коли позволено, но с умом, потому-то и потому-то.

deep-purple ★★★★★
()
Ответ на: комментарий от Crocodoom

Одномерный — чтобы было в одном куске. При работе кастуешь к четырёхмерному

Бже, как страшно. Тщем, недавно пилил бинарное дерево поиска (чистая сишка) — там кажный вузел в отдельном куске памяти, и чо? Ну... наверное было б влупить выравнивание в структах и памяти, всё такое, но, только если это будет узким местом. А так то — нахрена?

deep-purple ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.