EmbeddedRelated.com
Forums

Strange IAR warning Pe550

Started by Albert Bartoszko December 19, 2003
Hi!

Why i get:
[...]
IAR MSP430 C Compiler V2.21B/W32 [Kickstart]
Copyright 1996-2003 IAR Systems. All rights reserved.
Warning[Pe550]: variable "TA_vector" was set but never used
[...]

when compile timerA interrupt function with body:
------------------------

--------------------------

Generated code is as expected.

Albert

Beginning Microcontrollers with the MSP430

Hi!

It looks that a warning should be issued but I will have to take a
look at it later...

However, I don't think that the code that is generated by that
expression really does what you want. In fact it will actually *jump*
into the table, which doesn't seem right.

You can either write:

TA_vector[TAIV/2]();

Or,

typedef void fp(void);
((fp *)*(int *)((char *)TA_vector + TAIV))();

The generated code differs slightly, the first requires a right + left
shift of the value in TAIV (due to C array semantics) while the second
generates the code I think that you're after.

As a extra bonus, neither of the two suggested versions generates a
warning (maybe the warning isn't wrong after all?).

-- Anders Lindgren, IAR Systems
--
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.
From: "Anders Lindgren" <andersl@ande...>
[...]
> However, I don't think that the code that is generated by that
> expression really does what you want. In fact it will actually *jump*
> into the table, which doesn't seem right.

Yes, I only want to show a warning.

[...]
> typedef void fp(void);
> ((fp *)*(int *)((char *)TA_vector + TAIV))();
>

Why "int"?
I'm surprised ;-)

I prefer:
typedef void fp(void);
(*(fn **)((char *)TA_vector + TAIV))();

or
(*(void (**)(void))((char *)TA_vector + TAIV))()

[...]
> As a extra bonus, neither of the two suggested versions generates a
> warning (maybe the warning isn't wrong after all?).

Yes, this is a kind of bonus you get and not know about it ;-)

Thanks for answer, and Merry Christmas for all.

Albert
Hi,

> I prefer:
> typedef void fp(void);
> (*(fn **)((char *)TA_vector + TAIV))();

Why not simply
(*(void(*)())TA_vector + TAIV)();
?

Regards

Rolf F.
From: "Rolf F." <rolf.freitag@rolf...>
[...]
> > I prefer:
> > typedef void fp(void);
> > (*(fn **)((char *)TA_vector + TAIV))();
>
> Why not simply
> (*(void(*)())TA_vector + TAIV)();
> ?
>

Because it's bad?

It not compile in KickStart at all.

IAR MSP430 C Compiler V2.21B/W32 [Kickstart]
Copyright 1996-2003 IAR Systems. All rights reserved.
Error[Pe852]: expression must be a pointer to a complete object type

In mspgcc it complie, but it call a table, not function in it, as
((void (*)(void))((char *)TA_vector + TAIV))()
in my first question.

Albert
Hi,

> In mspgcc it complie, but it call a table, not function in it

Ok, that's the difference.


> (*(void(*)())TA_vector + TAIV)();
>
>
>Because it's bad?
>
>It not compile in KickStart at all.
>
> IAR MSP430 C Compiler V2.21B/W32 [Kickstart]
> Copyright 1996-2003 IAR Systems. All rights reserved.
>Error[Pe852]: expression must be a pointer to a complete object type

That's a compiler error because (*(void(*)())ADDRESS)(); is correct and
common ANSI-C:

http://www.literateprogramming.com/ctraps.pdf page 3 and 4

Rolf F.
From: "Rolf F." <rolf.freitag@rolf...>
[...]
> That's a compiler error because (*(void(*)())ADDRESS)(); is correct and
> common ANSI-C:
>
> http://www.literateprogramming.com/ctraps.pdf page 3 and 4

Yes, but problem is not in conversion.

(*(void(*)())ADDRESS)() - works OK

(*(void(*)())ADDRESS+ INTEGER)() - no

Problem is if compiler know size of
*(void(*)())ADDRESS ;-)

IAR compiler think no, mspgcc yes.
Who has right?

Albert
Hi,

>>That's a compiler error because (*(void(*)())ADDRESS)(); is correct and
>>common ANSI-C:
>>
>>http://www.literateprogramming.com/ctraps.pdf page 3 and 4
>>
>>
>
>Yes, but problem is not in conversion.
>
>(*(void(*)())ADDRESS)() - works OK
>
>(*(void(*)())ADDRESS+ INTEGER)() - no
>
>Problem is if compiler know size of
> *(void(*)())ADDRESS ;-)
>
>IAR compiler think no, mspgcc yes.
>Who has right?
>

mspgcc because
(*(void(*)())ADDRESS)()

means jump to ADDRESS (e. g. BR ADDRESS) and the only problem can be
that ADDRESS is not aligned.

Rolf F.
From: "Rolf F." <rolf.freitag@rolf...>
[...]
> >Who has right?
> >
>
> mspgcc because
> (*(void(*)())ADDRESS)()
>
> means jump to ADDRESS (e. g. BR ADDRESS) and the only problem can be
> that ADDRESS is not aligned.

What about
(*(void(*)())ADDRESS + 1)() ?

Is this call ADDRESS + 1 ? (as mspgcc thing)
or ADDRESS + 2 ? (as shoud be for msp430)
or something else?



Albert
> >Yes, but problem is not in conversion.
> >
> >(*(void(*)())ADDRESS)() - works OK
> >
> >(*(void(*)())ADDRESS+ INTEGER)() - no
> >
> >Problem is if compiler know size of
> > *(void(*)())ADDRESS ;-)
> >
> >IAR compiler think no, mspgcc yes.
> >Who has right?
> >
>
> mspgcc because
> (*(void(*)())ADDRESS)()
>
> means jump to ADDRESS (e. g. BR ADDRESS) and the only problem can be
> that ADDRESS is not aligned.

That doesn't mean JUMP TO ADDRESS. There is no generalised goto in ANSI
C.

Picking this apart:

void(*)() - is a pointer to a function taking UNSPECIFIED arguments.
(void(*)())ADDRESS - casts ADDRESS to a pointer to a function taking
UNSPECIFIED arguments.
*(void(*)())ADDRESS - is a function constant taking UNSPECIFIED
arguments
(*(void(*)())ADDRESS)() - is a call to a function constant taking
UNSPECIFIED arguments.

There is no goto in here, only a regular call. I agree with IAR, simply
because you can't write something like:

void foo(void) { ... }

void main(void)
{
f(); // ok
(f+1)(); // WTF does that mean?
}

This perfectly mimics (*(void(*)())ADDRESS+ INTEGER)() with something
mortals can unsertand and it doesn't mean anything--it's adding a number
of a function, which is NOT specified by ANSI C. Hell, if somebody can
tell me where it is, I'll buy them a beer. It's completely bogus and
IAR is correct to diagnose the problem. Just because the GNU compiler
compiles it doesn't mean its valid ANSI C code.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for MSP430 and ARM processors