This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Compiler error 143

Can anyone tell me why this piece of code builds with error 143, and how to get it to build without errors?

typedef unsigned char U8;
typedef unsigned long int U32;

#define B0(x) ((U8) ((U32)x&0xFF))
#define B1(x) ((U8)(((U32)x&0xFF00)>>8))
#define B2(x) ((U8)(((U32)x&0xFF0000)>>16))
#define B3(x) ((U8)(((U32)x&0xFF000000)>>24))

void foo(void);

BYTE abc[]={
    B0(foo),
    B1(foo),
    B2(foo),
    B3(foo)
};

void foo(void){
}

Thanks... Dave.

  • I don't have the C166 compiler, so I don't know what error 143 is.

    The thing that leaps out at me is that the value of foo is not known until link time. So, the compiler can't break it up into individual bytes in the initializer expression. You can get away with some forward references to an entire address, since it will be just another location for a fixup for the linker. But I'm not sure it's possible for the compiler to tell the linker to do fixups of just some byte of the target address.

    If all you want is byte-wise access to the bytes of a function address, why not just cast it?

    If you're trying to store a function address in some sort of vector table, why not just have a table of function pointers instead of bytes?

  • "I don't have the C166 compiler, so I don't know what error 143 is."

    Neither do I!

    Dave, you'd really help yourself in getting an answer to your question if you posted the full text of the message.

    Have you looked up this error in the Manual?
    Did that add anything?
    Did it help?

  • OOOPS...

    the word "BYTE" should be replaced with "U8"

    Sorry for the bad code snippet (hopefully there aren't any other silly errors in it!).

  • MY BAD...! I thought only C16x tool user's would've attempted to answer my question, although I do appreciate your help. FWIW, KEIL's user's manuals are online now. Not sure how long they've been online, but... the compiler reports:

    MAIN.C(35): error 143: 'scalar': initializer is not a constant
    

    The array of bytes I'm trying to create at build time contains a variety of instances of differently sized info, some of which are pointers to functions, encoded as an array of bytes. Doesn't appear to be possible to do to me, but I'm hoping it is.

    Thanks again...
    Dave.

  • Hm. It does sound like what I mentioned earlier, then. Since the compiler doesn't know the value of foo at compile time, it can't calculate (U32)foo >> 24 (for example) to be part of the initializer.

    Presumably you know which bytes are which in this array. If the data is structured, could you declare a struct for the data, and then initialize that struct? E.g.,

    typedef struct
       {
       U8 someByte;
       void (*f)(void);  // alignment restrictions on C166?
       U16 someCounter;
       } HeterogeneousData;
    
    HeterogeneousData abc =
       {
       0,
       foo,
       0xdead
       };
    

    If you later need to access that memory as an array of bytes, just cast: ((U8*)&abc).

    The other fallback I would suggest is to initialize the memory array at run time. That will likely cost you a few more bytes of code, though.

  • "initializer is not a constant"

    It often pays to simply read the text of an error message out loud - it is telling you exactly what Drew has been saying!
    The value of foo is not known at compile time; thus it is not a constant!

  • Thanks to all of you who participated in my enlightenment, especially those who provided the technical answer (hence, understanding) I was looking for. Thankfully there are many different ways I can attempt to solve the related problem, and I'm on my merry way towards an alternative solution.