I am using the IAR C compiler to build an application for an embedded micro (specifically a Renesas uPD78F0537). In this application I am using two nested for loops to initialize some data, as shown in the following MCVE:
#include <stdio.h>
#define NUM_OF_OBJS 254
#define MAX_OBJ_SIZE 4
unsigned char objs[NUM_OF_OBJS][MAX_OBJ_SIZE];
unsigned char srcData[NUM_OF_OBJS][MAX_OBJ_SIZE];
void main(void)
{
srcData[161][2] = 10;
int x, y;
for (x = 0; x < NUM_OF_OBJS; x++)
{
for (y = 0; y < MAX_OBJ_SIZE; y++)
{
objs[x][y] = srcData[x][y];
}
}
printf("%d\n", (int) objs[161][2]);
}
The output value is 0, not 10.
The compiler is generating the following code for the for loop:
13 int x, y;
14 for (x = 0; x < NUM_OF_OBJS; x++)
\ 0006 14.... MOVW DE,#objs
\ 0009 16.... MOVW HL,#srcData
15 {
16 for (y = 0; y < MAX_OBJ_SIZE; y++)
\ 000C A0F8 MOV X,#248
17 {
18 objs[x][y] = srcData[x][y];
\ ??main_0:
\ 000E 87 MOV A,[HL]
\ 000F 95 MOV [DE],A
19 }
\ 0010 86 INCW HL
\ 0011 84 INCW DE
\ 0012 50 DEC X
\ 0013 BDF9 BNZ ??main_0
20 }
The above does not work: The compiler is apparently precalculating NUM_OF_OBJS x MAX_OBJ_SIZE = 1016 (0x3f8). This value is used as a counter, however it is being truncated to 8 bits (0xf8 == 248) and stored in 8-bit register 'X'. As a result, only the first 248 bytes of data are initialised, instead of the full 1016 bytes.
I can work around this, however my question is: Is this a compiler bug? Or am I overlooking something?
Update
- This microcontroller has 7KB of RAM, and sizeof(int) == 2
- Copying the data over using pointers (e.g. something along the lines of
while (len-- > 0) *dst++ = *src++;
) works fine.
srcData
is initialized. If it isn't initialized explicitly, then what is the point of this code? – Resolublechar
toint
parameter. – Leslielesly