реклама на сайте
подробности

 
 
> преобразование указателя, возможно ли такое
TigerSHARC
сообщение Sep 4 2012, 11:31
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195



есть стандартная функция ioctl (функция области ядра в Linux).
Эта функция должна принимать указатель и модифицировать адрес на который он указывает. Но проблема в том, что прототип функции таков, что функция может принимать только unsigned int значение.
А посему возникает вопрос: можно ли в принципе преобразовать адрес указателя в unsigned int и обратно?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 9)
Сергей Борщ
сообщение Sep 4 2012, 11:46
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (TigerSHARC @ Sep 4 2012, 14:31) *
А посему возникает вопрос: можно ли в принципе преобразовать адрес указателя в unsigned int и обратно?
Можно, явным приведением типа, но это будет работать только если размер unsigned int не меньше размера указателя.

unsigned int A = (unsigned int)Pointer;


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Sep 4 2012, 11:57
Сообщение #3


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



И главное, не забыть подробно задокументировать этот костыль


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
SSerge
сообщение Sep 4 2012, 19:59
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



В 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.

Но они не обязательны, а главное, так саму проблемму всё равно не решить, можно только спрятать её поглубже.
Реализация функции всё равно должна знать разрядность данных с которыми работает.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
редактор
сообщение Sep 5 2012, 06:03
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



Не уверен (поскольку не имею документального подтверждения, кроме личного убеждения), но кажется размер указателя всегда равен размеру переменной типа int.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 5 2012, 06:38
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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.



--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ReAl
сообщение Sep 5 2012, 11:08
Сообщение #7


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Сергей Борщ @ 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-ов, где третьего аргумента нет вообще, где указатель в чистом виде.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
редактор
сообщение Sep 6 2012, 06:44
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



Цитата
имевшие 16-битный int и 32-битный far pointer

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



--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 6 2012, 07:04
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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
.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ReAl
сообщение Sep 6 2012, 07:43
Сообщение #10


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(редактор @ 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 ("Невроз"), в процессе перетаскивания кое-чего из уже успевшего быть написанным :-)


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 20:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01433 секунд с 7
ELECTRONIX ©2004-2016