Robert S. Barnes
Robert S. Barnes

Reputation: 40578

Can the size of pointers vary between data and function pointers?

I was just reading the section of the C FAQ on pointers.

It discusses not being able to use void * pointers to hold function pointers because pointers to data and pointers to functions may have differing sizes on some platforms and void * is only guaranteed be large enough to hold pointers to data.

Can anyone give an example of a platform where pointers to data and pointers to functions actually have differing sizes?

Upvotes: 27

Views: 9193

Answers (6)

Jonathan Leffler
Jonathan Leffler

Reputation: 754760

Note that POSIX requires pointers to objects and pointers to functions to be the same size:

2.12.3 Pointer Types

All function pointer types shall have the same representation as the type pointer to void. Conversion of a function pointer to void * shall not alter the representation. A void * value resulting from such a conversion can be converted back to the original function pointer type, using an explicit cast, without loss of information.

Note: The ISO C standard does not require this, but it is required for POSIX conformance.

Consequently, systems that claim POSIX-compliance will be uniform. If you only target such machines, then you do not have to worry about the differences.

Upvotes: 7

pmg
pmg

Reputation: 108988

> 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 generates code in the "compact" model; tcc -mm generates code in the "medium" model

Upvotes: 12

Clifford
Clifford

Reputation: 93556

16-Bit PIC microcontrollers (Microchip PIC24 and dsPIC) are examples of Harvard architecture devices with different data and code space pointer sizes. The separate address spaces differ in size - on chip SRAM has a greater chip-area cost that Flash memory, there is much less of it, so data pointers can be smaller.

This is also true of PIC12, PIC16, and PIC18 architectures also, but dsPIC is what I happen to be using currently.

Upvotes: 8

Stephen Canon
Stephen Canon

Reputation: 106287

Machines that use a Harvard Architecture have separate storage for instructions and data, and correspondingly have separate address spaces for instructions and data. In such an architecture, there is no real reason to have the two address spaces (or physical memory backing them) be the same size.

Upvotes: 5

Michael
Michael

Reputation: 55435

On real-mode x86, code & data is accessed by segment + offset, each a 16-bit quantity. "Near" pointers were 16-bit only and used the current segment, "Far" pointers were 32-bit and specified the segment and offset. For C compilers, there were several different memory models you could choose, with different defaults of near or far pointers for code and data.

For example, the "Medium" memory model used near pointers for data but far pointers for code by default.

I wouldn't be surprised if some modern embedded processors have similar memory models.

Upvotes: 9

olliej
olliej

Reputation: 36803

It's a "depends" situation. In C++ I recall that member function pointers are actually two pointers in size, but that may be purely an implementation detail.

In some of the really old pre-PC systems you could also have pointer size depend on what was being referenced (but then you could also have 11bit characters :D )

Upvotes: 1

Related Questions