powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / почему я тут не могу заменить reinterpret_cast на static_cast ?
24 сообщений из 24, страница 1 из 1
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002850
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пытаюсь понять в чем разница преобразований скажем reinterpret_cast и static_cast .

выходит разница все же есть.

вот этой программой пытаюсь расщепить число float (или double) на составляющие мантиса, степень...
так вот reinterpret_cast все выходит, а static_cast ругает.
текст ошибки :
static_cast: невозможно преобразовать "float *" в "unsigned char *"
а почему такие ограничения ???



а почему ???
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
#define TYPE float
#define TYPEPTR unsigned char*
void printBinary1(const unsigned char val)
{
    for (int i = 7; i >= 0; i--)
        if (val & (1 << i)) std::cout << "1"; else std::cout << "0";
    std::cout << ' ';
}
int main(int argc, char* argv[])
{

    if (argc < 2) { cout << "Must provide a number" << endl; exit(1); }
    TYPE d = atof(argv[1]);
    TYPEPTR cp; //= reinterpret_cast<TYPE2>(&d);
    TYPEPTR cp1; //= (TYPE2)(&d);
    argv++;
    while (argc-- >= 2)
    {
        d = atof(*argv++);
        cp = static_cast<TYPEPTR>(&d);
        std::cout << d << '\t';
        for (int i = sizeof(TYPE) - 1; i >= 0; i -= 1)
            printBinary1(cp[i]);
        std::cout << endl;
    }

}



кстати в стиле классического Си cp = (TYPEPTR)(&d); получается нормально !
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002858
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,

static_cast предназначен для приведения между типами для которых существует встроенное или пользовательское преобразование (из float в int, например).
Между типами float* и char* таких преобразований нет.

У reinterpret_cast другое предназначение - (там список длинный вообще-то, но в частности) приведение между типами совместимыми в соответствии с правилами алиасинга.
Как в вашем случае.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002865
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
andron81,

static_cast предназначен для приведения между типами для которых существует встроенное или пользовательское преобразование (из float в int, например).
Между типами float* и char* таких преобразований нет.

примечательно , что float * -> void * тоже пользовательским преобразованием считается :)
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002875
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
andron81,

static_cast предназначен для приведения между типами для которых существует встроенное или пользовательское преобразование (из float в int, например).
Между типами float* и char* таких преобразований нет.

В этой концепции непонятно почему указатель на базовый класс можно преобразовать к указателю на класс
наследника с помощью static_cast?
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002878
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravпочему указатель на базовый класс можно преобразовать к указателю на класс
наследника с помощью static_cast?

Потому что метод такого преобразования известен во время компиляции. Отсюда его название
"static".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002887
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravпочему указатель на базовый класс можно преобразовать к указателю на класс
наследника с помощью static_cast?

Потому что метод такого преобразования известен во время компиляции. Отсюда его название
"static".

И каким же образом ты указатель на базовый класс собрался преобразовывать в указатель на
класс наследника во время компиляции?
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002897
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81
примечательно , что float * -> void * тоже пользовательским преобразованием считается :)

Не пользовательским а встроенным ))
Это специальный указатель к/из которому можно приводить любой. Фича досталась от С.
Это можно считать вырожденным случаем приведения к указателю на базовый класс, про который выше писали.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002898
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
И каким же образом ты указатель на базовый класс собрался преобразовывать в указатель на
класс наследника во время компиляции?

У компилятора есть вся инфа, чтобы сгенерить нужный код, который будет один и тот же для любых экземпляров этих классов.
static, другими словам )).
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002899
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
petrav
И каким же образом ты указатель на базовый класс собрался преобразовывать в указатель на
класс наследника во время компиляции?

У компилятора есть вся инфа, чтобы сгенерить нужный код, который будет один и тот же для любых экземпляров этих классов.
static, другими словам )).

Ну посмотрим:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
// Experimental.h
struct S1
{
    virtual ~S1() = default;
};

// main.cpp
#include "Experimental.h"

struct S2: S1
{};

void foo(S1 *s)
{
    S2 *p = static_cast<S2 *>(s);
}

// Experimental.cpp
#include "Experimental.h"

void foo(S1 *s);

struct S3: S1
{};

void bar()
{
    foo(new S3());
}


Это собирается и я не вижу оснований для такого лихого преобразования от базового
класса к наследнику.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002901
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Это собирается и я не вижу оснований для такого лихого преобразования от базового
класса к наследнику.

Ну все правильно. Никто не обещал диагностировать UB. Ведь приводить можно или вниз или вверх по иерархии, а не в бок ))
В foo компилятор не знает о классе S3 (и не имеет такой возможности). Он работает с теми типами о которых вы ему сообщили.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002903
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
petrav
Это собирается и я не вижу оснований для такого лихого преобразования от базового
класса к наследнику.

Ну все правильно. Никто не обещал диагностировать UB. Ведь приводить можно или вниз или вверх по иерархии, а не в бок ))
В foo компилятор не знает о классе S3 (и не имеет такой возможности). Он работает с теми типами о которых вы ему сообщили.

Чисто формально я понимаю почему так отработал static_cast. Но очевидно, что он не должен производить преобразования к наследникам. И поведение static_cast ну... противоречит вашим словам о встроенных и пользовательских преобразованиях.

Т.е. я так же как вы и сказали понимаю static_cast. Но тут как обычно косяк.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002908
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravИ каким же образом ты указатель на базовый класс собрался преобразовывать в указатель на
класс наследника во время компиляции?

Внезапно: вычитанием из него константы.

Сравни результат преобразования к наследнику с помощью dynamic_cast, static_cast и
reinterpret_cast. "Сурпрайз будет..." (с)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002911
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravИ каким же образом ты указатель на базовый класс собрался преобразовывать в указатель на
класс наследника во время компиляции?

Внезапно: вычитанием из него константы.

Сравни результат преобразования к наследнику с помощью dynamic_cast, static_cast и
reinterpret_cast. "Сурпрайз будет..." (с)

Внезапно, но в точке преобразования указателя предка к наследнику у тебя нет информации об
этой константе. Сурпрайз, не?

PS: Конечно, речь идёт о static и static_cast.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002912
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravСурпрайз, не?

Реально сурпрайз. Я всегда был уверен, что класс наследника должен быть объявлен перед
преобразованием к нему. Покажешь компилируемый код, где это не так?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002913
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravСурпрайз, не?

Реально сурпрайз. Я всегда был уверен, что класс наследника должен быть объявлен перед
преобразованием к нему. Покажешь компилируемый код, где это не так?

Ну вообще не верно ни в каких смыслах. Про static_cast код выше.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002915
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81
примечательно , что float * -> void * тоже пользовательским преобразованием считается :)
К void* приводится любой указатель, кроме указателя на виртуальную метод.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002916
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
И каким же образом ты указатель на базовый класс собрался преобразовывать в указатель на
класс наследника во время компиляции?
Указателей на тип не существует в принципе. Существует лишь указатель на экземпляр типа - на объект.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002917
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
petrav
И каким же образом ты указатель на базовый класс собрался преобразовывать в указатель на
класс наследника во время компиляции?
Указателей на тип не существует в принципе. Существует лишь указатель на экземпляр типа - на объект.

Не придирайтесь к словам. Мы не в юридической конторе работаем. Я всё сказал максимально понятно.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002918
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravПро static_cast код выше.

И? Всё объявлено, смещение S2 относительно S1 равно sizeof(VMT*) или 0 по выбору компилятора.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002921
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravПро static_cast код выше.

И? Всё объявлено, смещение S2 относительно S1 равно sizeof(VMT*) или 0 по выбору компилятора.

И то, что в точке компиляции static_cast (в моём примере) у компилятора нет информации о
правомерности преобразования S1* в S2*. Это не информация static (этап компиляции), это
информация этапа runtime и static_cast не имеет права заниматься такими преобразованиями
раз он не имеет о нём информации.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002923
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravЭто не информация static (этап компиляции), это информация этапа runtime и static_cast не
имеет права заниматься такими преобразованиями раз он не имеет о нём информации.

Runtime информация это всего лишь правомочность такого преобразования. Само преобразование
сугубо одинаково. И именно в этом отличие static_cast от dynamic_cast: runtime проверка
правомочности.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002925
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravЭто не информация static (этап компиляции), это информация этапа runtime и static_cast не
имеет права заниматься такими преобразованиями раз он не имеет о нём информации.

Runtime информация это всего лишь правомочность такого преобразования. Само преобразование
сугубо одинаково. И именно в этом отличие static_cast от dynamic_cast: runtime проверка
правомочности.

Если преобразование называется static, то оно должно работать корректно на этапе компиляции.
Должно! Если такое преобразование не имеет на этапе компиляции информации о данном
преобразовании, то такое static преобразование и не должно компилироваться.
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40002928
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravне должно компилироваться

Раз компилируется - значит имеет.

А за полной защитой от дурака, это к языкам четвёртого поколения.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
почему я тут не могу заменить reinterpret_cast на static_cast ?
    #40003165
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andron81,

> почему такие ограничения ???

Намеренно, ибо противоестественный акт такого каста требует самый грубый каст.

Static_cast предназначен для сужения типа, а у вас разные типы.

Однако, вы можете сделать каст через void*, как в вашей другой теме. Void* - самый широкий класс, его можно сузить до любого типа.
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / почему я тут не могу заменить reinterpret_cast на static_cast ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]