Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

Strange Compiler Behaviour -

Strange Compiler Behaviour -

2005-02-23 by Mark Butcher

Hi All

Can anyone explain the following?

Here's the code (important fragments only):


***********************************
extern IDINFO que_ids[];

static unsigned short entry_spi(void)
{
return 0;
}

a_function()
{
unsigned short usDriverID = 2;
unsigned short (*entry_add)(void) = entry_spi;

que_ids[usDriverID].ulEntryAddress = entry_add; /* HERE */
}
***********************************
Works fine - /* HERE */ is compiled to the following assembler code 
by IAR compiler.

LDR R0,[PC,#0x090]
SRP R0,[R6,#0]



However when the external que_ids is defined as
extern IDINFO *que_ids;
-----------------------
the program doesn't work any more. If I compile and run the same 
code using Visual C++ however it works also fine.

The IAR compiler creates in this case the following code:
LDR R0,[PC,#0x09c]
LDR R1,[PC,#0x0A0]
LDR R1,[R1,#0]
LDR R2,[SP,#4]
STR R0,[R1,R2]

In fact what it does is uses the value of que_ids[0].ulEntryAddress 
as a reference pointer plus some offset to store the value of 
entry_add and this is somewhere in the middle of RAM no-mans-
land...causing program failure.



extern IDINFO que_ids[]; and extern IDINFO *que_ids; should be 
equivalent as far as I am aware and this is the first instance where 
I have found two compilers producing completely different code (one 
seemingly false).

Any Gurus out there with any comments? Could it be an IAR specific 
problem or is it more delicate than that?

Cheers

Mark Butcher

www.mjbc.ch

Re: [lpc2000] Strange Compiler Behaviour -

2005-02-23 by Robert Adsett

At 04:42 PM 2/23/05 +0000, Mark Butcher wrote:
>extern IDINFO que_ids[]; and extern IDINFO *que_ids; should be
>equivalent as far as I am aware and this is the first instance where
>I have found two compilers producing completely different code (one
>seemingly false).

They are not equivalent.  The first is the name of an array, the second is 
a pointer to an element.  The first gets replaced by the linker with a 
reference to the array location in memory, the second by a reference to a 
pointer to a location in memory.

What you are probably thinking of are the fact that array syntax and 
pointer syntax can be used interchangeably in many circumstances.  This is 
one of the exceptions.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,
be they legal, genetic, or physical.  If you don't believe me, try to
chew a radio signal. "

                         Kelvin Throop, III

RE: [lpc2000] Strange Compiler Behaviour -

2005-02-23 by Paul Curtis

Hi, 

> extern IDINFO que_ids[]; and extern IDINFO *que_ids; should 
> be equivalent as far as I am aware and this is the first 
> instance where I have found two compilers producing 
> completely different code (one seemingly false).

They certainly are NOT equivalent!  The first says that que_ids is an
array of IDINFO elements based at que_ids (e.g. an array starting at
0x4000).  The second says que_ids is a pointer to a IDINFO based at
que_ids (e.g. at 0x4000 there is a pointer to an array).

You can boil this down really easily:

static int xa[10];
static int *xp;
extern int xae[];

// Assign the address of I to the pointer P
xp = &i;

// Try doing that with an array
xa = &i;  // won't have it.

// Or an external unspecified array
xae = &i;  // won't have it.

Simple.  User error.

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

Re: Strange Compiler Behaviour -

2005-02-24 by Mark Butcher

Hi Robert

I'm still not convinced and did some more tests. As reference I am 
testing using Visual C++ compiler [for clarification I prefer to 
develop on the PC where the hardware is simulated and then compile 
for the target when it all seems to work - this tends to be much 
faster than debugging on the target and is only an issue when new 
hardware features have to be integrated..(for example finding out 
the issue with SSEL pul up..)]

So here we go:

First simple comparison tests to ensure that the syntax should be 
valid..

extern int iArray[];
extern int *ptr;  // note that ptr is externally set to iArray using 
either ptr = iArray or ptr = &iArray[0];

iArray[20] = 99;
ptr[20] = 100;
ptr += 20;
*ptr = 101;
When I step throug the code I get the confirmation that the same 
address in memory is set to 99 then 100 and then 101, confirming 
that the access to the array is functioning using the three 
different methods.

Then I studied the code which was not working on the target compiled 
with IAR.

Here is what happens with Visual studio C++ compiler (whith assemble 
commented by myself).

extern IDINFO que_ids[];

que_ids[usDriverID].ulEntryAddress = entry_add;
00403A57   mov         edx,dword ptr [ebp-4]        // load usDriver 
value to edx
00403A5A   and         edx,0FFFFh                   // mask to 
unsigned short
00403A60   imul        edx,edx,14h                  // calculate 
offset from start of array (IDINFO is 0x14 long)
00403A63   mov         eax,[_que_ids (0042c684)]    // load the 
start address of que_ids to eax
00403A68   mov         ecx,dword ptr [ebp-14h]      // load the 
value in entry_add to ecx
00403A6B   mov         dword ptr [eax+edx],ecx      // store 
entry_add value from ecx to que_ids start + (offset IDINFO length * 
usDrive)

and here is what happens with the other declaration

extern IDINFO *que_ids;  // Note que_ids = &que_ids_array[0];

00403A45   mov         eax,dword ptr [ebp-4]        // load usDriver 
value to edx
00403A48   and         eax,0FFFFh                   // mask to 
unsigned short
00403A4D   imul        eax,eax,14h                  // calculate 
offset from start of array (IDINFO is 0x14 long)
00403A50   mov         ecx,dword ptr [ebp-14h]      // load the 
value in entry_add to ecx
00403A53   mov         dword ptr _que_ids (0042c684)[eax],ecx  // 
store entry_add value from ecx to que_ids pointer address + (offset 
IDINFO length * usDrive)

As can be seem the second solution is slightly more efficient 
because it is not necessary to load the start address of que_ids 
since it is already in the variable called que_ids. An offset to the 
entry in the structure/array can be accessed directly.

Maybe there was confusion since I didn't point out that que_ids is 
of course initialised with the address of an array (which is 
dynamically allocated using malloc in the real case).

Therefore my conclusion is that the Visual C++ compiler treats these 
two cases as 'equivalent' and can possibly even be more efficient 
using the second declaration (where of course the pointer value is 
set to the start of the array in question).

Do you not agree that then the IAR compiler should therefore produce 
assembler code which works and doesn't cause the system to fail?

Regards

Mark Butcher

www.mjbc.ch

PS I will look at the IAR assembler again later - maybe there is an 
explaination in the details...

--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> 
wrote:
> At 04:42 PM 2/23/05 +0000, Mark Butcher wrote:
> >extern IDINFO que_ids[]; and extern IDINFO *que_ids; should be
> >equivalent as far as I am aware and this is the first instance 
where
> >I have found two compilers producing completely different code 
(one
> >seemingly false).
> 
> They are not equivalent.  The first is the name of an array, the 
second is 
> a pointer to an element.  The first gets replaced by the linker 
with a 
> reference to the array location in memory, the second by a 
reference to a 
> pointer to a location in memory.
> 
> What you are probably thinking of are the fact that array syntax 
and 
> pointer syntax can be used interchangeably in many circumstances.  
This is 
> one of the exceptions.
> 
> Robert
> 
> " 'Freedom' has no meaning of itself.  There are always 
restrictions,
> be they legal, genetic, or physical.  If you don't believe me, try 
to
Show quoted textHide quoted text
> chew a radio signal. "
> 
>                          Kelvin Throop, III

Re: Strange Compiler Behaviour -

2005-02-24 by Mark Butcher

Hi Robert

OK - you were right. It was working on the Windows PC because the 
module is really getting its memory from heap and uses a pointer. 
The other declaration (static array) was also working but only by 
chance since it was setting and collecting from a 'free' location.

I realised that the target build (testing a new module) was using a 
previous base still with static arrays and so the new module was 
failing.

At least I had the change to get my head around and now it's clear.

Regards

Mark Butcher

www.mjbc.ch

--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> 
wrote:
> At 04:42 PM 2/23/05 +0000, Mark Butcher wrote:
> >extern IDINFO que_ids[]; and extern IDINFO *que_ids; should be
> >equivalent as far as I am aware and this is the first instance 
where
> >I have found two compilers producing completely different code 
(one
> >seemingly false).
> 
> They are not equivalent.  The first is the name of an array, the 
second is 
> a pointer to an element.  The first gets replaced by the linker 
with a 
> reference to the array location in memory, the second by a 
reference to a 
> pointer to a location in memory.
> 
> What you are probably thinking of are the fact that array syntax 
and 
> pointer syntax can be used interchangeably in many circumstances.  
This is 
> one of the exceptions.
> 
> Robert
> 
> " 'Freedom' has no meaning of itself.  There are always 
restrictions,
> be they legal, genetic, or physical.  If you don't believe me, try 
to
Show quoted textHide quoted text
> chew a radio signal. "
> 
>                          Kelvin Throop, III

Re: [lpc2000] Re: Strange Compiler Behaviour -

2005-02-24 by Robert Adsett

At 01:27 PM 2/24/05 +0000, Mark Butcher wrote:
>OK - you were right. It was working on the Windows PC because the
>module is really getting its memory from heap and uses a pointer.
>The other declaration (static array) was also working but only by
>chance since it was setting and collecting from a 'free' location.

I won't reply to your other message then :).  I think this is an area where 
the similarity of Cs syntax usage rules on [] between pointers and arrays 
coupled with the automatic conversion of array name to pointer causes 
people to build up false models.  You are certainly not the only person to 
run afoul of it.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,
be they legal, genetic, or physical.  If you don't believe me, try to
chew a radio signal. "

                         Kelvin Throop, III

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.