Yahoo Groups archive

Lpc2000

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

Message

Re: For C Experts

2006-03-31 by Guillermo Prandi

This is indeed a strange piece of code:

char buf[]={1,2,3,4,5,6,7,8};
int *ip, x[10];
for (i=0; i<4; i++)
{
ip = (int *)&buf[i];
x[4]  = *ip;
}

(I made x[10] as dsidlauskas1 said).

This code will repeatedly (and pointlessly) change the value of the 
memory addresses x+16 through x+19. The first time (if alignment and 
aliasing were non-issues) it would write 0x01020304 (or 0x04030201, 
depending on endianness); the second time it would write 0x02030405; 
the third time, 0x03040506; and the fourth and last time it would 
write 0x04050607.

I think that this piece of code is so confusing that I was lost in 
what it does or what it should do and became unsure about the span of 
the original question.

Anyway, regarding alignment problems: the packed attribute or pragma 
(depends on the compiler) may permit to treat some data with 
unaligned access. I am unsure if this extends to pointers. Consider 
the following declaration:

struct {
char x;
int y;
} st;

This implies unaligned access to st.y ONLY if a "packed" pragma or 
attribute was specified. If no "packed" attribute was used, then st.y 
would be exactly four bytes counting from &st (three bytes are lost 
after st.x). In GCC, you do this packing like this:

struct {
char x;
int y;
} st __attribute__((packed));

But I am not aware of any way of specifying such thing for an int 
pointer like this:

int* x __attribute__((packed)); /* this does not work */
/* gives warning: attribute packed ignored */

So I am not so convinced that "packed" is a solution. At least not 
without a previous investigation on each and every target compiler 
(you mentioned at least two: Keil and GCC... would them behave 
similarly on this?). You must be cautious about this.

The second thing to watch for is aliasing. Last week I was attempting 
something like this:

void func(int par);

int main(void)
{
float a = 1.0f;
func(*(int*)&a);
}

And then:
void func(int par)
{
float x;
x = *(float*)\u2225
...do something with x...
}

The reasons I was doing this are too long and shameful to explain 
here, but the point is that it didn't work at all. It worked nicely 
if I compiled with aliasing optimization off, but as soon as I used 
size or speed optimization, it became broken. First of all, I had to 
make some of the casting volatile, like this:

extern void func(int par);
float a = 1.0f;
func(*(volatile int*)&a);

If I didn't add the volatile modifier I sometimes didn't get "x" sent 
as the parameter "par", but some other value (usually the value that 
should have been sent in a previous call to func()). Next (and 
worst), I just had to replace the func() part by some inline 
assembling: there was no way I could get "x" (from func()) to get the 
correct value due to aliasing.

The point is: beware of these "it is not standard but it should work" 
type of constructs. They give you more headaches than you may 
anticipate. Perhaps an in-depth revision of your old Z-80 code would 
pay you better, no matter how long it is.

Guille

--- In lpc2000@yahoogroups.com, "jayasooriah" <jayasooriah@...> wrote:
>
> Dave,
> 
> The satement "x[4] = ..." trashes memory where the the fifth element
> of the array "x[]" would normally exist, because you have declared 
it
> as "x[4]" which means it has only four elements.  Hence the array
> bound problem.
> 
> Jaya
> 
> --- In lpc2000@yahoogroups.com, "dsidlauskas1" <dsidlauskas@> wrote:
> >
> > I don't think its out of bound. X[4] is the 5th location in the
> > buffer, &x[4] is it's address, and there are 4 bytes declared from
> > theis address (5, 6, 7, 8).
> > 
> > Anyway, for the purpose of this example initialize the first 20
> > locations of buf.
> > 
> > --- In lpc2000@yahoogroups.com, David Hawkins <dwh@> wrote:
> > >
> > > dsidlauskas1 wrote:
> > > > Consider the following code:
> > > > 
> > > > ============================
> > > > char buf[]={1,2,3,4,5,6,7,8};
> > > > int *ip, x[4];
> > > > 
> > > > for (i=0; i<4; i++)
> > > >     {
> > > >     ip = (int *)&buf[i];
> > > >     x[4]  = *ip;
> > > >     }
> > > 
> > > Er, given the fact that x is of length 4,
> > > the statement x[4] = *ip is actually out-of-bounds.
> > > 
> > > Dave
> > >
> >
>

Attachments

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.