malloc просто выделяет пустое пространство (без предположения об объекте, который будет туда помещен)
Правильно.Динамически выделяемая память, в частности, не имеет типа до того момента, когда вы что-то напишите в эту область.Формально язык C называет это эффективным типом .Формальное определение находится в C17 6.5 / 7:
эффективный тип объекта для доступа к его сохраненному значению является объявленным типом объекта, если таковой имеется.Если значение сохраняется в объекте, у которого нет объявленного типа, через lvalue, имеющий тип, который не является символьным типом, то тип lvalue становится эффективным типом объекта для этого доступа и для последующих доступов, которые не изменяютсохраненное значение.
То, что возвращается из malloc, - это просто необработанный кусок памяти, без специальных атрибутов, до точки, где вы пишете в эту область.После чего компилятор должен нанести на него «метку типа».Как только вы получите к нему доступ с помощью [], компилятор должен будет предположить, что выделенные данные должны рассматриваться как массив, чтобы система типов оставалась согласованной между статически размещенными и динамически размещаемыми объектами.
Аналогичнообласть памяти становится структурой в точке, когда вы обращаетесь к памяти, так как она будет иметь отступы и т. д. и будет определять смещение памяти каждого элемента.Поэтому, если дана структура с противоположным порядком вашего примера, например:
struct test {
char a;
int b;
};
Тогда это определяется реализацией, если x->b
приведет к доступу к байту 1, байту 4 или чему-то еще, так каккомпилятор может свободно добавлять отступы между членами.
Но как только вы получите доступ к x->something
, компилятору придется начать с любых 1026 * точек в качестве эффективного типа struct test
или системы типов.не будет вести себя последовательно.