I tried to program this code on an STM8 Controller:
#include "Imagedata.h"
void main(void)
{
unsigned char *pArray;
pArray=IMAGE_DATA;
while(pArray<=(IMAGE_DATA (sizeof(IMAGE_DATA)/sizeof(pArray))))
{
SPI_SendData(SPI1,*pArray );
}
}
Actually the array is much longer than this but it would take to much space here. The Array is defined in imagedata.c:
#include "imagedata.h"
const unsigned char IMAGE_DATA[]= { 0X00,0X01,0XC8,0X00,0XC8,0X00};
After compiling this code I get the error message: array size unknown. This refers to the line where I put sizeof(IMAGE_DATA). I don't quiet understand what the problem is. Can anyone help?
CodePudding user response:
Your condition looks wrong, both the end value and comparison. Try this:
const unsigned char *pArray = IMAGE_DATA;
const unsigned char * const pEnd = pArray sizeof(IMAGE_DATA) / sizeof(*pArray);
while(pArray < pEnd) {
...
Note 1: sizeof char
is by definition 1, so / sizeof(*pArray)
part is a bit redundant. Matter of taste if it makes code clearer or not.
Note 2: It's a common pattern, and explicitly allowed by C, to have "end" pointer which is one past the end of the range. Just be sure to never do *pEnd
.
Note 3: IMAGE_DATA
must be array for sizeof
to work. It must not be a pointer, or an "array" parameter to function (because that is also a pointer, not really array).
Note 4: IMAGE_DATA
is const, so you need a pointer to const. As a side note, code in this answer makes pEnd
a const pointer to const, because the end pointer itself shouldn't be accidentally changed, but this is also a matter of taste and optional.
So your actual problem is, IMAGE_DATA isn't fully defined array. Either the definition must include initialization:
char foo[] = { 33, , 34 , 35 }; // compliers counts size 3
Or with explicit size:
char foo[3];
CodePudding user response:
There's multiple problems here.
- Try to avoid using global variables with
extern
in the first place. Implementing setter/getter functions in imagedata.h/imagedata.c is likely a better design. Use private encapsulation whenever possible. - In case the array in the header file is declared as
extern const unsigned char IMAGE_DATA[];
you will get the mentioned error message. This creates a reference to an array of "incomplete type". You have to type out the size explicitly likeIMAGE_DATA[6]
, meaning that it probably doesn't make sense to writeconst unsigned char IMAGE_DATA[]=
in the .c file either, because you have to count the bytes anyway. pArray=IMAGE_DATA;
is a constraint violation of the C language. You cannot assign a non-const qualified pointer to a const qualified array.sizeof(pArray)
is nonsense since it gives the size of a pointer, not of a pointed-at item.sizeof
a character is guaranteed to be 1 anyway, so this is all rather pointless.while(pArray<=
will lead to out of bounds access, use<
. Also usefor
loops whenever possible since tend to be more readable.- Note
#include "imagedata.h"
vs#include "Imagedata.h"
. This will only work on host systems where the file path isn't case-sensitive. So you create a needless non-portability issue between Windows and *nix systems. Always name sources files in pure lower case.
Proposed fixes:
// imagedata.h
/*
Normally size_t would be used for array size, but since this is STM8 I picked a
byte type, under the assumption that size will not be larger than 256.
*/
const char* image_get_data (unsigned char* size);
// imagedata.c
#include "imagedata.h"
static const unsigned char IMAGE_DATA[]= { 0X00,0X01,0XC8,0X00,0XC8,0X00};
const char* image_get_data (unsigned char* size)
{
*size = (unsigned char) sizeof(IMAGE_DATA);
return IMAGE_DATA;
}
// main.c
#include "imagedata.h"
void main(void)
{
const unsigned char *pArray;
unsigned char size;
parray = image_get_data(&size);
for(unsigned char i=0; i<size; i )
{
SPI_SendData(SPI1, pArray[i]);
}
}
Note: in case you are using some god-awfully old STM8 compiler, which might be a valid scenario, then disassemble and see if this gave decent machine code. A possible micro-optimization might be to sacrifice some of the private encapsulation for speed:
// imagedata.h
static inline const char* image_get_data (unsigned char* size)
{
static const unsigned char IMAGE_DATA[]= { 0X00,0X01,0XC8,0X00,0XC8,0X00};
*size = (unsigned char) sizeof(IMAGE_DATA);
return IMAGE_DATA;
}