Какие формулировки в стандарте C ++ допускают static_cast <non-void-type *> (malloc (N)); работать? - PullRequest
7 голосов
/ 10 апреля 2010

Насколько я понимаю формулировку в 5.2.9 Статическом приведении, единственный раз, когда разрешен результат преобразования void* в объект-указатель, это когда void* был результатом обратного преобразования в первое место.

Во всем стандарте имеется множество ссылок на представление указателя, и представление указателя void совпадает с представлением указателя char и т. Д., Но, кажется, оно явно не указывается скажем, что приведение произвольного указателя void дает указатель на то же место в памяти, с другим типом, очень похожим на определение типа, которое не определено, если нет возврата к фактическому типу объекта.

Так что, хотя malloc явно возвращает адрес подходящей памяти и т. Д., Я не вижу никакого способа использовать его, как я уже видел, по-портативному.

Ответы [ 3 ]

3 голосов
/ 10 апреля 2010

C ++ 0x стандартная версия имеет в 5.2.9 / 13:

Значение типа указатель на cv1 пустота »может быть преобразовано в значение введите «указатель на cv2 T», где T является тип объекта и cv2 одинаковы квалификация как или выше cv-квалификация, чем, cv1. Ноль значение указателя преобразуется в ноль значение указателя типа назначения. Значение типа указатель на объект преобразуется в «указатель на cv void» и назад, возможно, с разными CV-квалификация, должна иметь свою Исходное значение.

Но также обратите внимание, что приведение не обязательно приводит к действительному объекту:

 std::string* p = static_cast<std::string*>(malloc(sizeof(*p)));
 //*p not a valid object 
2 голосов
/ 18 января 2011

C ++ 03, §20.4.6p2

Содержимое совпадает с заголовком стандартной библиотеки C со следующими изменениями: [список изменений, которые здесь не применяются]

C99, §7.20.3.3p2-3

(Хотя C ++ 03 основан на C89, у меня есть только C99 для цитирования. Однако я считаю, что этот раздел семантически не изменился. §7.20.3p1 также может быть полезен.)

Функция malloc выделяет пространство для объекта, размер которого определяется размером и чье значение не определено.

Функция malloc возвращает либо нулевой указатель, либо указатель на выделенное пространство.

Из этих двух кавычек malloc выделяет неинициализированный объект и возвращает указатель на него или возвращает нулевой указатель. Указатель на объект, который у вас есть как пустой указатель, может быть преобразован в указатель на этот объект (первое предложение C ++ 03 §5.2.9p13, упомянутое в предыдущем ответе).


Это должно быть меньше "ручного махания", на которое вы жаловались, но кто-то может возразить, что я "интерпретирую" определение malloc C, как мне хотелось бы, например, заметив, что C говорит "выделенному пространству", а не «выделенному объекту». Тем людям: во-первых, понять, что «пространство» и «объект» являются синонимами в Си, а во-вторых, пожалуйста, подайте отчет о дефектах в стандартные комитеты, потому что даже я не настолько педантичен, чтобы продолжать. :)

Я дам вам преимущество сомнения и верю, что вы запутались в перекрестных ссылках, перекрестной интерпретации и иногда запутанной интеграции между стандартами, а не в «пространстве» и «объекте».

1 голос
/ 13 декабря 2011

Во всем стандарте имеется множество ссылок на представление указателя, а представление пустого указателя, совпадающее с представлением указателя на символ ,

Да, действительно.

Таким образом, хотя malloc четко возвращает адрес подходящей памяти и т. Д., Я не вижу никакого способа использовать его, как я видел, по-переносному.

Конечно, есть:

void *vp = malloc (1);
char *cp;
memcpy (&cp, &vb, sizeof cp);
*cp = ' ';

Есть одна крошечная проблема: она не работает для любого другого типа. (

...