Почему обязательно явно указывать типы malloc и calloc в C++?

Недавно я прочитал статью, в которой говорилось, что в C нет необходимости явно приводить типы malloc и calloc, но в C++ это обязательно. Почему это так? Кто-нибудь может объяснить?


person Paula    schedule 18.12.2019    source источник
comment
Отвечает ли это на ваш вопрос? Приведение типов malloc C++   -  person gstukelj    schedule 18.12.2019
comment
Я отредактировал теги, потому что вы спрашиваете о C++, но в C есть: передать результат malloc? В C полученная мудрость заключается не только в том, что это не нужно, но и нежелательно.   -  person Weather Vane    schedule 18.12.2019
comment
См. также это.   -  person    schedule 18.12.2019
comment
Короткий ответ, потому что void * в cpp не преобразуется неявно, тогда как в C это происходит. Так устроен язык.   -  person gstukelj    schedule 18.12.2019
comment
@gst Это действительно об этом. Затем ОП может спросить, почему С++ был разработан таким образом? Тогда это еще один вопрос, ведущий в какую-то кроличью нору.   -  person chux - Reinstate Monica    schedule 18.12.2019
comment
@chux-ReinstateMonica Я бы тоже хотел об этом услышать!   -  person gstukelj    schedule 18.12.2019
comment
Это правила С++. Эти функции возвращают void *. Если бы это было возможно, то вы могли бы сделать что-то простое вроде этого: void *ptr = nullptr; char* a = ptr;, но вы получите ту же ошибку без приведения.   -  person PaulMcKenzie    schedule 18.12.2019
comment
@gst: этот вопрос и ответы сортируются адрес, который   -  person user11923373    schedule 19.12.2019


Ответы (2)


Потому что в C очень часто нужно использовать void * для разных случаев. Некоторые из них являются файлами cookie для обратного вызова — когда вы предоставляете указатель на пользовательские данные, и у вас нет способа узнать этот тип данных. Или универсальные функции, такие как qsort(), они должны работать с различными данными, не зная заранее их тип. Однако в C++ вам не нужно использовать void * так часто, а в хорошем безопасном коде вам вообще не нужно их использовать, потому что у вас есть шаблоны, поэтому вы пишете общий код с использованием неизвестных типов без небезопасных преобразований. Поэтому создатели C++ хотели стимулировать правильное использование типов данных и убедиться, что когда разработчик выполняет небезопасные операции, он/она/оно/они понимает, что он/она/оно/они делает.

Поскольку malloc() и calloc() возвращают void *, вы должны явно преобразовать их в C++. Обратите внимание, что вы не должны использовать их в С++, а вместо этого использовать operator new, который уже возвращает правильный тип указателя, и вам не нужно приведение. И уж тем более в современном C++ не рекомендуется даже напрямую вызывать new.

person Slava    schedule 18.12.2019
comment
Люблю ответ! Но не могли бы вы отредактировать его, чтобы вместо него использовалась она/он или даже они? А еще лучше, может быть, переписать его, используя вас? - person gstukelj; 19.12.2019
comment
@gst конечно, держи - person Slava; 19.12.2019

В C ему задано T *tp; U *up; void *vp;, можно сказать vp = tp; up = vp; и в итоге получить U*, который содержит адрес T, без использования каких-либо операторов приведения. Разработчики C++, однако, хотели гарантировать, что подобное невозможно без использования хотя бы одного явного оператора приведения типов. В большинстве случаев требование использования оператора приведения между моментом представления указателя в виде void* и временем его фактического использования менее неприятно, чем требование оператора приведения при преобразовании указателя в void*, что и делает C++. Ни C, ни C++ не допускают каких-либо синтаксических различий между void*, который был создан путем преобразования адреса объекта с реальным типом, и тем, который используется для хранения адреса большого двоичного объекта хранения без типа и, следовательно, не имеет способ позволить последнему неявно преобразовываться в любой тип (что было бы полезно), не делая того же с первым (чего разработчики C++ не хотели).

person supercat    schedule 18.12.2019