Это, очевидно, ужасная техника, формально это неопределенное поведение и серьезная ошибка при вызове функции через несовместимый тип, но на практике она должна «работать» в нормальной системе.
На уровне машины ссылка и указатель имеют абсолютно одинаковое представление;они оба просто адрес чего-то.Я вполне ожидал бы, что fptr
и fref
скомпилируют одно и то же, инструкция для инструкции, на любом компьютере, на котором вы могли бы достать.Ссылку в этом контексте можно просто рассматривать как синтаксический сахар;указатель, который автоматически разыменовывается для вас.На уровне машины они точно такие же.Очевидно, что могут быть какие-то неясные и / или несуществующие платформы, где это может быть не так, но в целом это верно в 99% случаев.
Кроме того, на большинстве распространенных платформ все указатели объектов имеют одинаковое представление, как и все указатели функций.То, что вы сделали, на самом деле ничем не отличается от вызова функции, ожидающей int через тип long, на платформе, где эти типы имеют одинаковую ширину.Это формально незаконно и почти гарантированно работает.
Из определения malloc
можно даже сделать вывод, что все указатели объектов имеют одинаковое представление;Я могу malloc
огромный кусок памяти и вставить туда любой (в стиле C) объект, который мне нравится.Поскольку malloc
вернул только одно значение, но эту память можно повторно использовать для любого типа объекта, который мне нравится, трудно понять, как разные указатели объекта могут разумно использовать разные представления, если только компилятор не поддерживал большой набор отображений представления значений длякаждый возможный тип.
void *p = malloc(100000);
foo *f = (foo*)p; *f = some_foo;
bar *b = (bar*)p; *b = some_bar;
baz *z = (baz*)p; *z = some_baz;
quux *q = (quux*)p; *q = some_quux;
(Уродливые приведения необходимы в C ++).Вышеуказанное необходимо для работы.Поэтому, хотя я не думаю, что формально требуется потом memcmp(f, b) == memcmp(z, q) == memcmp(f, q) == 0
, но трудно представить себе разумную реализацию, которая могла бы сделать это ложным.
Как говорится, не делай этого!