Почему С++ запрещает неявное преобразование void *?

Вопрос:В C мы можем преобразовать void* в любые другие указатели. Но С++ запрещает это. int *a = malloc(4); приводит к этой ошибке: invalid conversion from ‘void*’ to ‘int*’ [-fpermissive] Есть ли скрытые опасности здесь, в С++? Есть ли примеры С++? Лучший ответ: В С++, в отличие от C, вы должны указать результат malloc. Ваш код

Вопрос:

В C мы можем преобразовать void* в любые другие указатели.

Но С++ запрещает это.

int *a = malloc(4);

приводит к этой ошибке:

invalid conversion from ‘void*’ to ‘int*’ [-fpermissive]

Есть ли скрытые опасности здесь, в С++?

Есть ли примеры С++?

Лучший ответ:

В С++, в отличие от C, вы должны указать результат malloc. Ваш код может быть изменен в рабочем порядке с простым приложением.

int *a = (int *)malloc(sizeof(int));

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

Изменить: Как указано в комментариях, использование malloc() не должно быть обычным явлением. Ближайшая альтернатива заключается в использовании new для выделения.

int *a = new int[15];

Дополнительное редактирование: Как снова предлагается в комментариях, если вам нужно использовать malloc(), по крайней мере, использовать С++-литье.

int *a = static_cast<int*>malloc(sizeof(int)); // shout out to @edheal, @mgetz Ответ №1

Вы можете выполнить преобразование в С++, но для этого требуется бросок. С++ стремится быть более безопасным для текста языком, чем C, поэтому он пытается закрыть некоторые “дыры в системе типов”, которые допускает C.

В C это будет приниматься без какой-либо диагностики:

int x; void *p = &x; double *q = p; *q = 0.0;

Безопасность типа была нарушена без каких-либо следов присутствия в исходном коде.

Это С++ FAQ, на который ответил Б. Страуструп, изобретатель С++.

С++ не запрещает преобразование; он просто хочет, чтобы он был документирован каким-то образом в исходном коде, а именно актом, который, по крайней мере, предлагает, если не доказывает, что это делается специально.

О происхождении void *, Stroustrup пишет это (смелый мой):

В конце своей истории C с классами * начал поддерживать понятие указателя на “необработанную память”, void *. Происхождение void * окутано какой-то тайной. Я смутно помню, как он изобрел его вместе с Ларри Рослер и Стив Джонсон. Тем не менее, Дэйв Проссер вспоминает сначала, предложив его на основе чего-то “где-то в Австралии”. Возможно, обе версии верны, потому что Дейв тесно сотрудничал с Ларри в то время. В любом случае void * был введен на обоих языках более или менее в то же время. Самое раннее упоминание void *, которое я могу найти, находится в памятке от 1 января 1983 года о механизмах управления памятью, предоставляемых моим компилятором С++, Cfront, поэтому происхождение void * на С++ должно вернуться к до середины 1982 года. Самая ранняя письменная запись void * в контексте ANSI C – это предложение Майка Мейснера от 12 октября 83 года, которое представило void * по существу, поскольку оно было принято в ANSI C в июне 1984 года [Prosser, 2001]

Таким образом, С++ наследует концепцию void *, как первоначально предполагал Stroustrup, в то же время люди C имели немного другую идею, которая была более свободной в безопасности типов.

В случае malloc, конечно, есть опасности; но они уже отмечены наличием известного идентификатора malloc; приведение не приводит к чему-либо еще, но не требует его специально для malloc, тогда как его требование везде будет неудобным исключением из правил.

* “C с классами” является предшественником С++

Оцените статью
Добавить комментарий