Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: преобразование указателя
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
TigerSHARC
есть стандартная функция ioctl (функция области ядра в Linux).
Эта функция должна принимать указатель и модифицировать адрес на который он указывает. Но проблема в том, что прототип функции таков, что функция может принимать только unsigned int значение.
А посему возникает вопрос: можно ли в принципе преобразовать адрес указателя в unsigned int и обратно?
Сергей Борщ
QUOTE (TigerSHARC @ Sep 4 2012, 14:31) *
А посему возникает вопрос: можно ли в принципе преобразовать адрес указателя в unsigned int и обратно?
Можно, явным приведением типа, но это будет работать только если размер unsigned int не меньше размера указателя.

unsigned int A = (unsigned int)Pointer;
MrYuran
И главное, не забыть подробно задокументировать этот костыль
SSerge
В C99 предлагается определять в файле stdint.h специальные типы intptr_t и uintptr_t :
Цитата
7.18.1.4 Integer types capable of holding object pointers
1 The following type designates a signed integer type with the property that any valid
pointer to void can be converted to this type, then converted back to pointer to void,
and the result will compare equal to the original pointer:
intptr_t
The following type designates an unsigned integer type with the property that any valid
pointer to void can be converted to this type, then converted back to pointer to void,
and the result will compare equal to the original pointer:
uintptr_t
These types are optional.

Но они не обязательны, а главное, так саму проблемму всё равно не решить, можно только спрятать её поглубже.
Реализация функции всё равно должна знать разрядность данных с которыми работает.
редактор
Не уверен (поскольку не имею документального подтверждения, кроме личного убеждения), но кажется размер указателя всегда равен размеру переменной типа int.
Сергей Борщ
QUOTE (редактор @ Sep 5 2012, 09:03) *
Не уверен
И правильно, что не уверены. IAR AVR: int = 16 bit, generic ptr - 24bit. Да и еще не так давно почившие 16-битные x86 приложения, имевшие 16-битный int и 32-битный far pointer:
QUOTE
For example, in an Intel 8086, as well as in later processors running 16-bit code, a far pointer has two parts: a 16-bit segment value and a 16-bit offset value. A linear address is obtained by shifting the binary segment value four times to the left, and then adding the offset value. Hence the effective address is 20 bits (actually 21-bit, which led to the address wraparound and the Gate A20). There can be up to 4096 different segment-offset address pairs pointing to one physical address. To compare two far pointers, they must first be converted (normalized) to their 20-bit linear representation.

ReAl
Цитата(Сергей Борщ @ Sep 5 2012, 09:38) *
Да и еще не так давно почившие 16-битные x86 приложения, имевшие 16-битный int и 32-битный far pointer:
А также вполне свежие x86_64 приложения (указатель 64 бита, int 32 бита, а вот long зависит от OS, причём временами это больно).

Цитата(TigerSHARC @ Sep 4 2012, 14:31) *
есть стандартная функция ioctl (функция области ядра в Linux).
...
Но проблема в том, что прототип функции таков, что функция может принимать только unsigned int значение.
Точно?
Цитата
#include <sys/ioctl.h>

int ioctl(int d, int request, ...);
Description
...
The third argument is an untyped pointer to memory.

И вот:
Цитата
real@ECSE2:/media/U2/real/o/avrprg/avreal/trunk/common$ grep -n ioctl lpt.cpp
lpt.cpp:339: claimed = ioctl(fd, PPCLAIM) == 0;
lpt.cpp:352: if (claimed && ioctl(fd, PPRELEASE)) {
lpt.cpp:368: ioctl(fd, PPRDATA, &value);
lpt.cpp:371: ioctl(fd, PPRSTATUS, &value);
lpt.cpp:374: ioctl(fd, PPRCONTROL, &value);
lpt.cpp:387: ioctl(fd, PPWDATA, &tmp);
lpt.cpp:392: ioctl(fd, PPWCONTROL, &tmp);
lpt.cpp:401: ioctl(fd, PPWDATA, pbuf++);
real@ECSE2:/media/U2/real/o/avrprg/avreal/trunk/common$
Никаких int-ов, где третьего аргумента нет вообще, где указатель в чистом виде.
редактор
Цитата
имевшие 16-битный int и 32-битный far pointer

Насколько я помню DOS и BC3.1, для получения 32-битного указателя требовалось ключевое сово far (расширение компилятора а не стандарт).
Для модели памяти типа LAGE все указатели были типа far pointer (BC3.1), а вот для модели SMALL генерился 16-битный указатель по умолчанию, и 32-битный с ключевым словом far.

Сергей Борщ
QUOTE (редактор @ Sep 6 2012, 09:44) *
для получения 32-битного указателя требовалось ключевое сово far (расширение компилятора а не стандарт).
Но от этого он не переставал быть указателем.

Да и что спорить? Стандарт говорит:
QUOTE
6.3.2.3 Pointers
3 An integer constant expression with the value 0, or such an expression cast to type
void *, is called a null pointer constant.
...
5 An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.

6 Any pointer type may be converted to an integer type. Except as previously specified, the
result is implementation-defined. If the result cannot be represented in the integer type,
the behavior is undefined. The result need not be in the range of values of any integer
type
.
ReAl
Цитата(редактор @ Sep 6 2012, 09:44) *
Насколько я помню DOS и BC3.1, для получения 32-битного указателя требовалось ключевое сово far (расширение компилятора а не стандарт).
Для модели памяти типа LAGE все указатели были типа far pointer (BC3.1),
Ну вот Вы сами себе и ответили.
Для моделей large и huge все указатели без дополнительного ключевого слова (near) не лезли в int.
А кусок исходника
Код
int *ptr;
int broken_ptr = (int)ptr;
сам по себе не знает, каким компилятором и с какой моделью памяти он будет компилироваться.

Собственно, уважительно относиться ко всему этому (сначала ещё к K&R1, потом к K&R2/ANSI) я и начал где-то в 88-91 годах при переходе с PDP-11 (ДВК) на x86 ("Невроз"), в процессе перетаскивания кое-чего из уже успевшего быть написанным :-)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.