0 / 0 / 0
Регистрация: 26.06.2016
Сообщений: 65
|
||||||
1 | ||||||
Приведение указателя базового типа14.08.2016, 12:00. Показов 4001. Ответов 23
У меня не получается выполнить приведение указателя базового типа. Я, и static_cast пробовал, и dynamic_cast пробовал, но компилятор всё равно выводит сообщение, что ptra - это не указатель.
0
|
14.08.2016, 12:00 | |
Ответы с готовыми решениями:
23
Приведение типа указателя Приведение типа указателя на метод Создание указателя типа базового класса на экземпляр производного класса Вызов виртуального метода базового класса из указателя производного |
183 / 181 / 66
Регистрация: 15.02.2015
Сообщений: 515
|
|
14.08.2016, 12:15 | 3 |
int* ptrb = reinterpret_cast<int*>(ptra);
0
|
0 / 0 / 0
Регистрация: 26.06.2016
Сообщений: 65
|
||||||
15.08.2016, 07:18 [ТС] | 5 | |||||
Возможно я скажу очень смешно, но я считал, что char, short, int, long, long long, float и double - это всё базовые элементарные типы данных.
Добавлено через 4 минуты А я читал что reinterpret_cast производит небезопасное приведение типа и его опасно использовать? Добавлено через 49 минут Я исправил код, но теперь у меня не выводится значение переменной a через приведённый указатель ptrb. Строка 13 делает неправильный вывод.
0
|
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
|
|
15.08.2016, 08:22 | 6 |
Это ожидаемо. В этом как раз и заключается "небезопасность" reinterpret_cast - ответственность за его использование целиком ложится на программиста. В данном случае short меньше, чем int, поэтому пытаясь интерпретировать память, где лежит значение short, как значение int, мы получаем чтение еще части чужих данных, которые вместе с числом 96 и составляют этот самый "неправильный" вывод.
Чтобы лучше это понять, возьми тетрадный лист, обведи там две клетки. Представь, что указатель &a указывает на первую из них. Когда ты приводишь такой указатель к int , то при попытке вывода значения будет чтиано еще две клетки за двумя обведенными. Понимаешь?
0
|
Падаван С++
447 / 261 / 89
Регистрация: 11.11.2014
Сообщений: 916
|
|
15.08.2016, 08:31 | 7 |
DrOffset, тогда вопрос, как с таким бороться или приходится кастовать к типам которые имеют такой же размер в байтах как и тот из которого мы приводим ? Или еще вариант если знааем на сколько бит больше тип к котором мы приводим, после "превращения" занулить лишние биты ?
0
|
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
|
||||||||||||||||
15.08.2016, 09:15 | 8 | |||||||||||||||
Как правило, так кастовать не нужно вообще. Если так получается, что нужен каст, то возможно что-то неправильно на более высоком уровне.
Рассматривать целесообразность можно на конкретной задаче. А для общего случая я могу сказать только "не делай так". Добавлено через 32 минуты obivan, что касается мер защиты, то в отдельных случаях (не обязательно связанных с кастами), можно предусмотреть дополнительные проверки времени компиляции. Например вот такой код:
Если нужно составить int из двух short, то каст к int * не нужен (в том числе из-за возможных проблем с выравниванием). Относительно безопасный способ - использовать memcpy (она на многих процессорах разворачивается в одну инструкцию), а еще безопаснее - битовые сдвиги. Например вот так:
1
|
Падаван С++
447 / 261 / 89
Регистрация: 11.11.2014
Сообщений: 916
|
|
15.08.2016, 09:30 | 9 |
вопрос по коду, просто чтобы уточнить, мы тут принимаем 2 типа и данная функция кастования будет доступна только в случае если тот тип к которому мы кастуем будет больше чем от которого происходит каст ?
P.S. очень понравился вариант со сдвигом
0
|
183 / 181 / 66
Регистрация: 15.02.2015
Сообщений: 515
|
||||||
15.08.2016, 09:43 | 10 | |||||
obivan, Вы серьёзно?
Добавлено через 3 минуты Если боязно использовать reinterpret_cast для побитового приведения базовых типов, то есть union :
reinterpret_cast - лучше использовать для приведения типов указателей (как правило из void* в указатель на класс), не связанных иерархией наследования.
0
|
Падаван С++
447 / 261 / 89
Регистрация: 11.11.2014
Сообщений: 916
|
|
15.08.2016, 09:50 | 11 |
0
|
15.08.2016, 09:51 | 12 | |||||
Может лучше static_assert?
0
|
Падаван С++
447 / 261 / 89
Регистрация: 11.11.2014
Сообщений: 916
|
|
15.08.2016, 09:51 | 13 |
Operok, P.S все, я сейчас более трезво персмотрел код все ок
0
|
DrOffset
|
15.08.2016, 09:52
#15
|
0
|
HelicopterK52
|
15.08.2016, 09:54
#16
|
Не по теме: DrOffset, видимо, я мало спал :wall: Ну ладно, хоть пример привел, малая, да польза от сообщения всё же есть :D
0
|
183 / 181 / 66
Регистрация: 15.02.2015
Сообщений: 515
|
||||||
15.08.2016, 10:05 | 17 | |||||
Что значит "активно"? Приведите пример UB.
0
|
15.08.2016, 10:13 | 18 |
Фактически, Вы сами его привели
Для которого есть явное указание: Плюс ко всему, WinAPI рассчитан на C, со всеми вытекающими. http://stackoverflow.com/quest... d-behavior http://stackoverflow.com/quest... in-c-and-c
0
|
183 / 181 / 66
Регистрация: 15.02.2015
Сообщений: 515
|
||||||
15.08.2016, 10:26 | 19 | |||||
Простой способ разбить тип REAL (стандартное 4-байтное число с плавающей точкой) в массив байт с "тупоконечным" (4-3-2-1) порядком байт (например по модбасу отправить):
т.е. в данном случае UB возможно если платформа не поддерживает 64-битное целое? Это не UB, так как в таком случае оно даже не скомпилится.
0
|
15.08.2016, 11:06 | 20 |
Запись в одно поле и чтение из другого - вот это само по себе UB.
Пройдите по ссылкам Выше, там достаточно на эту тему написано. Добавлено через 36 минут Пост (прост он мне показался самым легким) из одной из статей и самопальный перевод:
4
|
15.08.2016, 11:06 | |
15.08.2016, 11:06 | |
Помогаю со студенческими работами здесь
20
Приведение указателя на функцию Приведение void* указателя к типу Приведение void* к типу указателя на структуру Приведение указателя на void к другому типу? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |