Подтвердить что ты не робот

Может ли размер указателей варьироваться между данными и указателями функций?

Я просто читал раздел C FAQ по указателям.

В нем обсуждается невозможность использования указателей void * для удержания указателей функций, поскольку указатели на данные и указатели на функции могут иметь разные размеры на некоторых платформах, а void * гарантированно будет достаточно большим, чтобы удерживать указатели на данные.

Может ли кто-нибудь привести пример платформы, где указатели на данные и указатели на функции имеют разные размеры?

4b9b3361

Ответ 1

> type ppp.c
#include <stdio.h>
#include <stdlib.h>

int global = 0;

int main(void) {
    int local = 0;
    static int staticint = 0;
    int *mall;
    int (*fx)(void);

    fx = main;
    mall = malloc(42); /* assume it worked */
    printf("#sizeof pointer to local: %d\n", (int)sizeof &local);
    printf("#sizeof pointer to static: %d\n", (int)sizeof &staticint);
    printf("#sizeof pointer to malloc'd: %d\n", (int)sizeof mall);
    printf("#sizeof pointer to global: %d\n", (int)sizeof &global);
    printf("#sizeof pointer to main(): %d\n", (int)sizeof fx);
    free(mall);
    return 0;
}
> tcc -mc ppp.c
Turbo C  Version 2.01 ...
warnings about unused variables elided ...
Turbo Link  Version 2.0 ...
> ppp
#sizeof pointer to local: 4
#sizeof pointer to static: 4
#sizeof pointer to malloc'd: 4
#sizeof pointer to global: 4
#sizeof pointer to main(): 2
> tcc -mm ppp.c
> ppp
#sizeof pointer to local: 2
#sizeof pointer to static: 2
#sizeof pointer to malloc'd: 2
#sizeof pointer to global: 2
#sizeof pointer to main(): 4

tcc -mc генерирует код в "компактной" модели; tcc -mm генерирует код в модели "средний"

Ответ 2

В реальном режиме x86 доступ к коду и данным осуществляется с помощью сегмента + смещения, каждый из которых имеет 16-разрядное количество. Указатели "Near" были только 16-битными и использовали текущий сегмент, указатели "Far" были 32-битными и определяли сегмент и смещение. Для компиляторов C было несколько различных моделей памяти, которые вы могли бы выбрать, с разными значениями по умолчанию для указателей ближнего или дальнего порядка для кода и данных.

Например, модель памяти "Средняя" используется по умолчанию для указателей для данных, но по умолчанию указатели на код по умолчанию.

Я бы не удивился, если некоторые современные встроенные процессоры имеют похожие модели памяти.

Ответ 3

Обратите внимание, что POSIX требует, чтобы указатели на объекты и указатели на функции были одного размера:

2.12.3 Типы указателей

Все типы указателей функций должны иметь то же представление, что и указатель типа на void. Преобразование указателя функции в void * не должно изменять представление. Значение void *, возникающее в результате такого преобразования, может быть преобразовано обратно в исходный тип указателя функции с использованием явного приведения без потери информации.

Примечание:     Стандарт ISO C не требует этого, но он необходим для соответствия POSIX.

Следовательно, системы, требующие соответствия POSIX, будут одинаковыми. Если вы ориентируетесь только на такие машины, вам не нужно беспокоиться о различиях.

Ответ 4

16-разрядные микроконтроллеры PIC (Microchip PIC24 и dsPIC) являются примерами устройств архитектуры Гарварда с различными размерами указателя и кода пространства. Отдельные адресные пространства различаются по размеру - на чипе SRAM имеется больший размер области чипа, чем у флэш-памяти, там гораздо меньше, поэтому указатели данных могут быть меньше.

Это также относится к архитектурам PIC12, PIC16 и PIC18, но dsPIC - это то, что я сейчас использую.

Ответ 5

Машины, которые используют Harvard Architecture, имеют отдельное хранилище для инструкций и данных и соответственно имеют отдельные адресные пространства для инструкций и данных. В такой архитектуре нет реальной причины, чтобы два адресных пространства (или их физическая память) были одинакового размера.

Ответ 6

Это зависит от ситуации. В С++ я помню, что указатели на функции-члены на самом деле являются двумя указателями в размере, но это может быть чисто детальность реализации.

В некоторых из действительно старых систем до ПК вы также можете иметь размер указателя в зависимости от того, на что ссылались (но тогда вы также можете иметь 11 бит символов: D)