How to get the size of an array in PROGMEM

Hi all,

If I have an array like this:

        const char *demo_names[] = {
                PSTR ("Slide Down"),
                PSTR ("Slide Up"),
                PSTR ("Slide Right"),
                PSTR ("Slide Left"),
        };

I can do this:

        uint8_t string_count = sizeof (demo_names) / sizeof (*demo_names);

...and of course "string count" returns "4".

Now, I want to do the same thing with an array like this:

static const uint8_t font[] PROGMEM = {
        0x7c, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x7f, 0x7c,
        0x3e, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x3e, // 0

        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, // 1
        // ------- snip ------------
};

But "sizeof(font)" returns "2" (the size of a 16 bit pointer I assume?) and of course "sizeof(*font)" returns 1 (the size of each uint8_t element).

Is there a way I can make this work so that if, say, there are 100 bytes of type "uint8_t" I can get "100" as the count and "1" as the byte size?

Said another way, I would expect that if I instead had an array of uint32_t, "sizeof" would return "100 elements" and "4 bytes in each element"

Thanks!

-- Roger

Krupski:
"sizeof(font)" returns "2"

Can you prove that? For me, with that declaration, it returns 32 (as you'd expect).

PeterH:

Krupski:
“sizeof(font)” returns “2”

Can you prove that? For me, with that declaration, it returns 32 (as you’d expect).

Please grab the file “sizeof_test.zip” and compile/run it on any Arduino.

The code replicates the relevant parts of the driver that I’m working on (and having the problem with).

Please see what you come up with. Thanks!

– Roger

(edit to add): This is what the code prints on my end:

Font is at address 313

sizeof(_font) returns 2

sizeof(*_font) returns 1

Font: width 8, height 16, first char 48

Reading data from PROGMEM array:

0xF0, 0xF8, 0x0C, 0xC4, 0x0C, 0xF8, 0xF0, 0x00,
0x03, 0x07, 0x0C, 0x08, 0x0C, 0x07, 0x03, 0x00,
0x00, 0x10, 0x18, 0xFC, 0xFC, 0x00, 0x00, 0x00,
0x00, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08, 0x00,
0x08, 0x0C, 0x84, 0xC4, 0x64, 0x3C, 0x18, 0x00,
0x0E, 0x0F, 0x09, 0x08, 0x08, 0x0C, 0x0C, 0x00,
0x08, 0x0C, 0x44, 0x44, 0x44, 0xFC, 0xB8, 0x00,
0x04, 0x0C, 0x08, 0x08, 0x08, 0x0F, 0x07, 0x00,

sizeof_test.zip (1.19 KB)

You will have to pass the size in the call to setFont...

setFont (ibm_8x16, sizeof(ibm_8x16));

...and save the value to a static / global...

size_t setFont (const uint8_t *fontPtr, size_t const fontSize )
{
	_font = fontPtr;
        _fontSize = fontSize;

...and use the static / global instead of sizeof(_font).

OK that works... and I was just going to ask you "why can't I get the size of the array from a pointer to it" and the question answered itself...... the pointer is only a pointer to the thing... not the thing itself.

Thanks for the answer... now it seems so obvious.......... :slight_smile:

-- Roger

The distinction between pointers and arrays is subtle. Syntactically an array is equivalent to a pointer to the first element in the array, but when you refer to the array by its symbolic name the compiler also knows how big the variable is. When you refer to it without using its symbolic name, the compiler only knows its type i.e. that it is a pointer to an element. This is why the size information is lost when you pass an array value as a function parameter. To get around this you need to add an argument passing in the array size - the code that supplies the array as a function argument can use sizeof() to calculate the corresponding size.