LINUX.ORG.RU

[c]размер указателя

 


0

0

Собственно как узнать размер указателя в программе.
Интересует что-то типа sizeof(int), но для указателя.
На сколько я помню они имеют одинаковый размер и не зависят от типа, на который указывают.
Почему-то в голову лезет sizeof(void).

Всем заранее спасибо за помощь.

★★★★★

> На сколько я помню они имеют одинаковый размер и не зависят от типа, на который указывают.

Точняк.

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

Всем большое спасибо.

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

>> На сколько я помню они имеют одинаковый размер и не зависят от типа, на который указывают.

> Точняк.


Они имеют его на практике, но совсем не обязаны по стандарту. Единственное, что гарантируется, - перобразование к void* и обратно.

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

>>> На сколько я помню они имеют одинаковый размер и не зависят от типа, на который указывают.

>> Точняк.

>Они имеют его на практике, но совсем не обязаны по стандарту. Единственное, что гарантируется, - перобразование к void* и обратно.

Оо, тяжелая артиллерия подтянулась. Не буду спорить, стандарт давно читал. За попкорном бежать?

ierton ★★
()

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

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

>Они имеют его на практике, но совсем не обязаны по стандарту. Единственное, что гарантируется, - перобразование к void* и обратно.

Как срашно жить. В связи со сказаным 2 вопроса:

1) что именно написано в стандарте (честно - не читал) - говорится, что они не обязаны быть равны, или не говорится, что должны быть равны ?

2) все указатели на struct равны по размеру, или зависит от содержимого ?

(надо бы собраться да самому почитать, только некогда)

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

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

указатель на объект + индекс в vtable ?

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

> 1) что именно написано в стандарте (честно - не читал) - говорится, что они не обязаны быть равны, или не говорится, что должны быть равны ?

Ну вот, чем не повод найти уже стандарт и почитать=)

> 2) все указатели на struct равны по размеру, или зависит от содержимого ?

Для реализации С на интеловской архитектуре - ответ "все указатели равны по размеру". Как где ещё - незнаю.

В архитектурах с раздельной памятью программ и памятью данных по идее нужны два разных типа указателя, которые _в_принципе_ можно былобы сделать разной длины. Но так как есть стандарт С (а в нем нет поддержки разных адресных пространств), то для таких архитектур компилятор использует всякие приемы, чтобы всё равно всё свести к привычному void* и товарищам. Вот в avr-gcc так сделано.

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

6.2.5 Types

26. A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.
Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.

На счет "все приводимы к void*" и я ошибся.

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

Не помню точно, там довольно сложно реализовано. Основная сложность - множественное наследование.

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

А что с ними? Обычный указатель в сегмент кода, не?

Legioner ★★★★★
()

комментарии невозбранно доставляют

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

>Если приписать два плюса

, то станет совсем весело. Раньше интересовался этим вопросом - так указатель на метод, указатель на виртуальный метод варьируются в размерах на разных компиляторах (при одной архтитектуре) от четырех до двадцати байт. Двадцать дал какой-то вендовый, ЕМНИП. У GCC (x86), кажется, размер указателя на любой метод - 8 байт. Что мне, человеку далекому до совсем низкоуровнего понимания программирования, кажется вполне логичным - адрес объкта + адрес метода класса, таблица виртуальных функций наверняка вычисляема относительно адреса метода.

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

>>Если приписать два плюса

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

В MSVC++ ЕМНИП есть три внутренних типа указателя на метод - указатель на метод класса с одиночным наследованием, указатель на метод класса с множественным наследованием и указатель на метод класса с множественным виртуальным наследованием. В недрах некоторых либ они их лепят из указателя на void(*)() и контекста вызова через union.

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

>адрес объкта + адрес метода класса

Это я глупость сказал, адрес объекта тут совершенно ни при чем. Наверное адрес самой функции и адрес класса.

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

> адрес класса.

Точнее - адрес таблицы виртуальных функций класса. Класс-то он вещь в себе и адреса не имеет.

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

>Думается, что для 64 битных систем это не так
Посмотреть можно, а то у меня только 32, на ней 4.

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

>Ну вот, чем не повод найти уже стандарт и почитать=)

Похоже придётся. Меня, помнится, в своё время ещё типизацией памяти напугали, тоже хотелось бы разобраться

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

>All pointers to structure types shall have the same representation and alignment requirements as each other.

Спасибо.

>На счет "все приводимы к void*" и я ошибся.

Ну, вообще-то приведённый текст ещё не опровергает это предположение, он лишь предполагает, что void* и char* могут _хранится_ каким либо иным способом, чем остальные типы. Но это, как я понимаю, всё ещё допускает, что даже если voidPtr и floatPtr хранятся по разному, при voidPtr = floatPtr преобразование произойдёт правильно.

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

Понял, тогда да.

Вообще я немного не понимаю, ведь over 9000 библиотек преобразуют указатели туда и обратно как надо быть. Тому же OpenGL чёрте-чего только не передаётся через void*. Это что же получается, стандарт живёт сам по себе, софт сам по себе ? Если подумать, как только начинается чуть более низкоуровневое программирование, так сразу натыкаемся на подводные камни стандарта. Помню, надо было мне написать структуру данных, что то типа массива, в котором вместе хранились разные типы данных - float'ы, указатели, int'ы, struct'ы, итд. Объекты в этот массив соответственно добавлялись и удалялись, поэтому периодически производилась дефрагментация. Но, как выяснилось, в свежих стандартах память считается типизованной, т.е. если я выделил память под int, а потом запихал туда float, то мне ничего не гарантируется (привет fast inverse sqrt =). На практике, конечно, вряд-ли кто-то из разработчиков компиляторов захочет ломать существующий код, но всё же такое положение дел очень печально.

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

> стандарт живёт сам по себе, софт сам по себе ?

Да.

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


А ты хочешь, чтобы дюжина человек предусмотрела все детали на всех системах, которые были, есть и будут? Низкоуровневое на то и низкоуровневое. )))

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

>Ну вот, чем не повод найти уже стандарт и почитать=)

Зачем?! Если можно и так сразу посмотреть?!

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

> Это не важно. Главное, не гарантируется, что floatPtr = (float *) voidPtr; будет выполнено корректно.

ты что-то путаешь. В стандарте есть специальные слова, что если преобразовать T* в void* и потом обратно в T*, то получится то что было сперва. Конечно, если ты преобразуешь int* -> void* -> float* то тут с гарантиями хуже.

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

6.3.2.3 Pointers 1 A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

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

Верно. Давно читал и, проглядывая, не нашел этого пункта.

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