Conversion between ordinals and pointers is not portable
Модератор: Модераторы
Сорян за некропостинг, но тема не раскрыта. Одно дело - подавление warning'а, а другое - корректная обработка. Поверхностный гуглёж не дал информации на тему где, собственно, этот conversion не portable. Если это, например, где-то в арме, то может можно указать конкретные целевые платформы и компилятор перестанет возмущаться?
- Ichthyander
- энтузиаст
- Сообщения: 701
- Зарегистрирован: 04.04.2007 08:32:43
- Откуда: Астрахань
- Контактная информация:
ger0strat писал(а):Сорян за некропостинг, но тема не раскрыта. Одно дело - подавление warning'а, а другое - корректная обработка. Поверхностный гуглёж не дал информации на тему где, собственно, этот conversion не portable. Если это, например, где-то в арме, то может можно указать конкретные целевые платформы и компилятор перестанет возмущаться?
Предыдущий пост как раз об этом... PtrInt для Integer и PtrUInt для Cardinal
То есть
Код: Выделить всё
AnInteger:=PtrInt(APointer);
ACardinal:=PtrUInt(APointer);И наоборот
Добавлено спустя 2 минуты 31 секунду:
В любом случае, мне кажется если это используется в коде это не совсем красиво. Но я это тоже делаю )
Последний раз редактировалось Ichthyander 05.09.2018 16:29:29, всего редактировалось 1 раз.
Не вижу принципиальной разницы. Если трансляция указателя из знакового в беззнаковое not portable, а она произведена, то какая разница каким методом? Что отключение уведомлений, что неявное преобразование, не порождающее оных - скорее в стиле "я не вижу значит нет этого".
Вероятно, я не корректно выразился. Вопрос в том, в каких случаях и чем опасно такое преобразование и как обезопаситься. Сомневаюсь, что эту проверку вставили чтобы левых warning'ов в лог покидать. Если дело только в разрядности, то понятно, нужно использовать зависимый тип. А если дело в особенностях arm, powerpc или sparc, то правильнее как-то сообщить компилятору, что их поддержка не требуется.
Вероятно, я не корректно выразился. Вопрос в том, в каких случаях и чем опасно такое преобразование и как обезопаситься. Сомневаюсь, что эту проверку вставили чтобы левых warning'ов в лог покидать. Если дело только в разрядности, то понятно, нужно использовать зависимый тип. А если дело в особенностях arm, powerpc или sparc, то правильнее как-то сообщить компилятору, что их поддержка не требуется.
- Ichthyander
- энтузиаст
- Сообщения: 701
- Зарегистрирован: 04.04.2007 08:32:43
- Откуда: Астрахань
- Контактная информация:
1. Выше я допустил опечатку/ошибку. Вместо ACardinal написал AnIn64. PUInt как раз служат для приведения беззнакового (unsigned) целого к указателю.
2. Размер переменной типа указатель зависит от разрядности приложения, Integer и Cardinal не зависит, - это конкретный и довольно практичный пример, не буду вдаваться в теории и идеологии, так как не осилю аргументацию.
3. PtrInt и PtrUInt всегда равны размеру типа указателя, хотя являются целыми типами. И когда Вы их используете для приведения это правильно и предупреждения нет, так как Вы знаете что делаете. Примерно так
2. Размер переменной типа указатель зависит от разрядности приложения, Integer и Cardinal не зависит, - это конкретный и довольно практичный пример, не буду вдаваться в теории и идеологии, так как не осилю аргументацию.
3. PtrInt и PtrUInt всегда равны размеру типа указателя, хотя являются целыми типами. И когда Вы их используете для приведения это правильно и предупреждения нет, так как Вы знаете что делаете. Примерно так
- serbod
- постоялец
- Сообщения: 449
- Зарегистрирован: 16.09.2016 10:03:02
- Откуда: Минск
- Контактная информация:
Там еще могут быть приколы с порядком байтов в машинном слове. Если в языке есть специальная фича для преобразования числа в адрес, то надо ей пользоваться. А еще лучше не хранить числа в указателях и не пользоваться арифметикой указателей.
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
serbod, пока вы не используете ассемблер, порядок байт в машинном слове вас волновать не должен. PtrInt позаботится за вас.
а разве не ptrUint ?
Кроме того, слышал (на уровне "одна баба сказала") что фпц пытается (или пытался) вползти на платформы типа JVM, где вообще нет такого понятия, как указатель. И вот там арифметика с указателями точно зафейлится.
Кроме того, слышал (на уровне "одна баба сказала") что фпц пытается (или пытался) вползти на платформы типа JVM, где вообще нет такого понятия, как указатель. И вот там арифметика с указателями точно зафейлится.
-
MysticCoder
- постоялец
- Сообщения: 154
- Зарегистрирован: 14.09.2013 00:20:28
Немного раскрою тему:
конверсии Pointer <-> Cardinal работают нормально на 32х разрядных системах. на 64хразрядных это будет фактически конверсии типа Pointer(64 бит) <-> Cardinal(32 бит).
конверсии Pointer <-> PtrUInt на 32хразрядных будет выдавать Pointer(32 бит) <-> Cardinal(32 бит), на 64х разрядных Pointer(64 бит) <-> UInt64(64 бит).
Варнинг о непортируемости выливается в потенциальную ошибку в следующем случае в 64 разрядной системе, например:
конверсии Pointer <-> Cardinal работают нормально на 32х разрядных системах. на 64хразрядных это будет фактически конверсии типа Pointer(64 бит) <-> Cardinal(32 бит).
конверсии Pointer <-> PtrUInt на 32хразрядных будет выдавать Pointer(32 бит) <-> Cardinal(32 бит), на 64х разрядных Pointer(64 бит) <-> UInt64(64 бит).
Варнинг о непортируемости выливается в потенциальную ошибку в следующем случае в 64 разрядной системе, например:
Код: Выделить всё
var
xPixel : Pointer;
xNextPixel : Pointer;
...
xPixel := xBmp.Scanline[0];
xNextPixel := Pointer(Cardinal(xPixel) + SizeOf(Cardinal)); // xPixel может указывать на $1234567800000000; в xNextPixel же в этом случае попадет $0000000000000004;
xNextPixel^ := 0; // ну и пишем, возможно, в левый участок памяти 