LINUX.ORG.RU

[c++] получение адреса указателя

 


0

1

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

SceneNode* scn = smgr->CreateSceneNode();
int ptr = scn;//вот тут как
// и еще надо как то так
SceneNode* scn2 = ptr;

ЗЫ. не гоните сцаными тряпками, просто объясните, я в гугле не нашел

★★★

Последнее исправление: pozitiffcat (всего исправлений: 1)

> не гоните сцаными тряпками

А следовало бы.

Zenom ★★★
()

размер указателя 32бит на х86_32

Jetty ★★★★★
()

Если следовать стандарту, то указатель следует сохранять в usigned long, а никак не в int.

hippi90 ★★★★★
()

ой как не хорошо, я бы даже сказал некультурно и аморально.

mi_estas
()

А почему сразу не сделать scn2 = scn?
Зачем вообще приведение к целому нужно?

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

> size_t?

Вообще size_t не является корректным типом для храниения указателей, так как он не обязательно связан с размером указателя. Хотя на большинстве современных систем подойдёт. Но всё таки лучше uintptr_t из C99 и, соответственно, C++11.

kim-roader ★★
()
Ответ на: комментарий от schizoid

size_t должен быть достаточного размера, чтобы хранить индекс любого массива (или, что то же самое, должен быть не меньше размера максимально возможного объекта). При этом если мы берём 16 битные машины с сегментной адресацией, то size_t должен иметь размер в 16 бит, так как один объект не может быть больше сегмента. В то же время uintptr_t должен быть достаточного размера чтобы хранить указатель, то есть и адрес сегмента и смещение в нём, для чего требуется 32 бита.

kim-roader ★★
()

Как ни странно, указатели даже на x86 платформе могут быть сильно больше 4 байт. По моим сведениям размер может достигать 12-16 байт.

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

> По моим сведениям размер может достигать 12-16 байт.

да, в msvc для указателей на метод

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

> Если следовать стандарту, то указатель следует сохранять в usigned long, а никак не в int.

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

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

> Как ни странно, указатели даже на x86 платформе могут быть сильно больше 4 байт. По моим сведениям размер может достигать 12-16 байт.

да неужели? обосновать сможете?

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

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

Тем не менее, указатель - это число, и его можно сохранить в целочисленную переменную. Стандарт не определяет размер типов в байтах, он отдает это на откуп реализации, тем не менее утверждается, что тип unsigned long должен быть достаточным, чтобы сохранить указатель. Можете посмотреть исходники различных программ, например из coreutils, там вы встретите приведение (void *) к (unsigned long).

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

Но вот на винде unsigned long таки 32 битный. Поэтому косяк. И вообще, в C++11x можно же не парится и просто вывод типов использовать в виде auto, ну а если нет, тогда или какой-нить qptrdiff или же самому typedef сделать на uintptr_t или на нужный тип, чтобы не заморачиваться потом с чем-нибудь странным.

Gorthauer ★★★★★
()
Ответ на: комментарий от kim-roader

Действительно, забыл про сегментную адресацию -_\\\
Только, ЕМНИП, логическому адресу в 16-битной архитектуре хватит 20 бит, разве нет?

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

>Тут можно ознакомиться.

вы путаете, указатель на метод это два указателя - на объект и на функцию

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

>Стандарт не определяет размер типов в байтах, он отдает это на откуп реализации, тем не менее утверждается, что тип unsigned long должен быть достаточным, чтобы сохранить указатель

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

P.S. венда конечно во всех смыслах гениальное творение, в winapi очень любят передавать указатели в апи функции или сообщения в виде DWORD, LPARAM или WPARAM безо всякого контроля... какая уж там стабильность и безопасность.

s0L
()

Блеать, sizeof(указатель) - возвращает 4 байта, че тут гадать-то?, sizeof(long) - 4 байта, sizeof(long long) - 8 байт - это все на 32 битной убунте

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

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

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

> указатель на метод это два указателя - на объект и на функцию

могу добавить, что реализация указателей на методы зависит от конкретного компилятора, т.к. помимо непосредственно указателя, там могут быть дополнительные данные на усмотрение компилятора. как ни крути указатель на платформе x86 32бит не может быть больше 32бит, даже если есть PAE.

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

> если бы вендоразрабы были бы такие козлы что у них все глючно и нерабоче, онибы в первый год своей жизни загнулись, если они так делают как ты говоришь, значит так можно делать!

ну делай на здоровье, умник на убунте

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

>вы путаете, указатель на метод это два указателя - на объект и на функцию

Нет, это вы путаете. Это указатель на метод и он может быть больше 4 байт.

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

Создай указатель на функцию, и посмотри sizeof, будет 4 байт. Указатель это есть переменная которая хранит в себе адрес, и является 4 байт на x86 архитектуре, на то он и называется указателем, что указывает к какой ячейке памяти обратиться, а далее все зависит от структуры к которой кастится этот участок памяти, он может хоть килобайт весить

pozitiffcat ★★★
() автор топика

reinterpret_cast<> ?

Зачем вообще ты этого хочешь?

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от pozitiffcat

>Указатель это есть переменная которая хранит в себе адрес, и является 4 байт на x86 архитектуре, на то он и называется указателем, что указывает к какой ячейке памяти обратиться, а далее все зависит от структуры к которой кастится этот участок памяти, он может хоть килобайт весить

Бред.

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

>Создай указатель на функцию, и посмотри sizeof, будет 4 байт.

Вы таким образом и черпаете знания? Эпично так.

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

> Не сваливайте в кучу размер адреса архитектуры и указатели С++. Это разные вещи.

во первых, эти вещи неразрывно связаны, а во вторых, вы с этого начали

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

>не может

Ну вы и упёртый. Посмотрите ещё раз ссылку.

во первых, эти вещи неразрывно связаны, а во вторых, вы с этого начали

Ещё раз. Указатель в С++ это не тоже самое что и адрес на ассемблере. sizeof(pointer) > 4 вас не убеждает? Тогда я умываю руки.

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

> Ещё раз. Указатель в С++ это не тоже самое что и адрес на ассемблере. sizeof(pointer) > 4 вас не убеждает? Тогда я умываю руки.

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

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

> Только, ЕМНИП, логическому адресу в 16-битной архитектуре хватит 20 бит, разве нет?

Даже если говорить о привычном x86 железе в реальном режиме, то (0010 + FFFF << 4) больше 20 бит, а такие адреса использовались под High Memory Area, так что зацикливание адресов по 20 битам не подходит.

Кроме того в случае 16-битных регистров и сегментной адресации сегменты в принципе могут быть непересекающимися и складываться в 32-битный адрес.

kim-roader ★★
()

sizeof(int) необязательно будет равен sizeof(void *), поэтому, если какой-то кривой API вынуждает сохранять указатель именно в int, то возможны проблемы. Если же речь идет именно о 32-битном указателе и 32-битном int, то можно сделать так:

SceneNode *scn = smgr->CreateSceneNode();
int ptr = reinterpret_cast<int>(scn);
...
SceneNode *scn2 = reinterpret_cast<SceneNode *>(ptr);

Но вообще за такое конечно надо отрывать руки по самые колени.

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

> Нет, это вы путаете. Это указатель на метод и он может быть больше 4 байт.

Хотя конечно с точки зрения синтаксиса C++, указатель на функцию-член - это всего лишь один указатель, но на самом деле за ним скрывается нечто большее. Технически указатель на нестатическую функцию-член реализуется в виде указателя на код (сама функция) и указателя на данные (указатель на объект, для которого вызывается эта функция, иными словами this). Именно поэтому размер указателя на нестатическую функцию-член больше размера простого указателя.

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

>Хотя конечно с точки зрения синтаксиса C++, указатель на функцию-член - это всего лишь один указатель, но на самом деле за ним скрывается нечто большее. Технически указатель на нестатическую функцию-член реализуется в виде указателя на код (сама функция) и указателя на данные (указатель на объект, для которого вызывается эта функция, иными словами this). Именно поэтому размер указателя на нестатическую функцию-член больше размера простого указателя.

По-моему, ты гонишь. Помимо адреса функции там сохраняется адрес на vtbl или что-то типа того, но никак не на объект; hint: (object.*methodptr)().

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

>Технически указатель на нестатическую функцию-член реализуется в виде указателя на код (сама функция) и указателя на данные (указатель на объект, для которого вызывается эта функция, иными словами this).

Нет, речь именно про указатель на метод, а не указатель на объект. Эти понятия в С++ отделены и мешать их не стоит.

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

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

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

>сравнил размер функции с размером указателя

Чего?

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

uintptr_t есть в C, например. Плюс это говнецо вроде как в boost скопировали.

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

> По-моему, ты гонишь. Помимо адреса функции там сохраняется адрес на vtbl или что-то типа того, но никак не на объект; hint: (object.*methodptr)().

Твоя правда. Последним, где я применял указатели на функции-члены была собственная реализация делегатов много лет назад, вот видимо я и спутал функтор использующийся там (который обязан знать указатель на объект) и указатель на функцию-член.

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