C51 COMPILER V9.53.0.0 LX51 LINKER/LOCATER V4.66.30.0
I have the following (relevant) lines of code:
extern xdata uint8_t rtu_rx_buf[]; extern xdata uint8_t rtu_tx_buf[]; . . . struct{ uint8_t func; uint16_t start; uint16_t qty; uint8_t n; }xdata *p = &rtu_rx_buf[1]; . . . p = rtu_tx_buf; . . .
The first assignment to 'p' doesn't raise any complaints from the compiler or linker. The second, however, gives me the following warnings:
*** WARNING C182 IN LINE 98 OF C:\blahblahblah.c: pointer to different objects *** WARNING L25: DATA TYPES DIFFERENT
I'm pretty sure I don't see the difference; am I missing something here?
The plot thickens... If I do this instead, I get complaints about both assignments:
struct{ uint8_t func; uint16_t start; uint16_t qty; uint8_t n; }xdata *p; . . p = &rtu_rx_buf[1]; . . . p = rtu_tx_buf; . . .
Maybe something else I'm doing is offending it in a much more subtle way. To put things into context a little better, this code is within a case of a switch statement thusly:
case MB_FUNC_WRITE_MULTIPLE_REGISTERS: { struct{ uint8_t func; uint16_t start; uint16_t qty; uint8_t n; }xdata *p = &rtu_rx_buf[1]; uint16_t st = p->start; uint16_t q = p->qty; uint8_t n = p->n; uint8_t i; uint8_t data *dest; uint8_t xdata *src; if(blahblahblah){ . . . p = rtu_tx_buf; . . . } } break;
Leaving aside xdata:
p is a pointer to a struct;
rtu_tx_buf is an array.
Clearly, these are different objects ?
Don't you need some casting in there ?
The first assignment to 'p' doesn't raise any complaints from the compiler or linker.
That's because that is not an assignment. It's an initializer. Similar-looking syntax, rather different semantics.
The second, however, gives me the following warnings:
As it should. That line of code is dangerous. It fully deserves to trigger a warning.
@Hans-Bernhard Broeker - Why do you consider that line of code "dangerous"?
It's dangerous for at least three reasons:
1) it relies on generally unwarranted assumptions without so much as a comment about them 2) you had to ask about why you got a warning about it 3) there are much clearer ways to that job, while avoiding the problems
As the code is, neither that struct itself, nor the pointer hackery you use it in buys you anything worth having.
Sorry I asked. I guess this is the wrong place to seek help.
no, it is the correct place.
however if you want a fish it is the wrong place, if, however, you want to learn how to fish it is the right place
Welcome to the friendly world of the Keil forum.
But seriously, if you can ignore the style of certain respondents, then it's worth taking the underlying technical detail as given. I've followed the forum for quite a while now and I feel I've a good idea how many of the frequent respondents write. There are a few notable exceptions that clearly go to great lengths to post truly useful responses without any evidence of ego and even without resorting to the seriously ridiculous Please read the manual catchall.
Suffice it to say, I have picked up a number of points that I would probably have otherwise missed. So it's a thumbs up from me.
I'll let you decide what type has responded to you.
So did you try the casting ?
I did not try casting. I'm sure it would probably work. I have decided to take another approach to this "problem". Nobody actually tried to answer my question which is 'why do I get a warning for the assignment statement but not the initialization statement?'. I'm still curious as to why this technique is "dangerous", too. Seems fairly straightforward to me...
I've decided to try creating a monster union that includes the raw data buffer, a union of request structures, a union of response structures, and an exception response structure. Maybe that will keep me out of trouble.
Casting is definitely the most appropriate course, given the limited context provided, using warnings to detect bad coding style in prone to bite at some point. It is your job to understand the use and ramifications at each utilization, use comments to provide context and reminders about the what and why.
I think Hans-Bernhard Broeker has already mentioned that the semantics are different in the two cases, and while blunter than you might like, does speak to some truths. Try to think of the cleanest ways to express your ideas to the compiler, not the "throw paint till it sticks" method.
I thought I'd posted this - but, apparently, not.
Note that the 2 warnings you initially posted are from different tools: one is from the Linker; the other is from the compiler.
There's not enough context there to see which diagnostic refers to which source line, but I'd guess that the compiler warning refers to the assignment, whereas the linker warning refers to the initialisation?
This could also account for why the warnings changed when you changed to two assignments - but you didn't show the actual messages in that case.
But proper casting should have fixed them all...