Yahoo Groups archive

Lpc2000

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

Message

Re: For C Experts

2006-03-31 by dsidlauskas1

Cordeg,

Thanks for taking the time to comment. You've presented a though case,
but I'm not going to let my compiler off so easily :-).

In your case I think the compiler should throw an error, although it
does know that buf is byte aligned and...

In my case I think the compiler should compile working code.

I won't repeat all of the reasons, which are spread through the thread.

Thanks again.

Dave

--- In lpc2000@yahoogroups.com, "garycordelli" <gary@...> wrote:
>
> Dave:
> 
> While what you said may sound reasonable to humans, it is demonstrably
> not so certain in software. :-)
> 
> To be specific, what you have in your original example is *not* a
> simple structure.  Your new example "sets up" the compiler to *know*
> precisely what is going on, so -- if it is inclined to generate some
> nice byte-swapping/byte-copying code -- it knows that it will have to
> do so.
> 
> However, let's change your new example to something that would "look"
> more like the conditions present in your original example:
>     #pragma packed(4)
>     struct eg {
>         char x;
>         int y;
>         char z;
>         int w;
>     };
> 
> Now you have "properly aligned" ints, just as you did in your original
> example (in the case of x[4], for example).  But, then you introduced
> the casting operation.  Hmmm.  So, this would be, in effect, doing
> something like:
>     char buf[] = { 1, 2, 3, 4, 5, 6, 7, 8, ...};
> 
>     for (i = 0; i < 4; i++) {
>         struct eg *p = (struct eg*)&buf[i];
>         ...
> 
> Now, what happens when you try to read/write the p->y and p->w members
> of this structure?
> 
> "It depends!"
> 
> See, the compiler is likely to think that -- because you properly
> packed the structure -- it does not have to generate byte-copy kludges
> to access these members.  They appear properly aligned to access using
> LDR.  HOWEVER, what happens if the whole darn structure STARTS at an
> odd address?  Well, that odd *external* alignment quite simply defeats
> the whole benefit of the proper *internal* alignment, ruining the
> best-laid plans of the compiler and you.  And, what exactly is it that
> defines "bad" *external* alignment of the structure?  Is it when "i"
> is not a multiple of 4?  NO.  NO?  NO.  It is when the ADDRESS OF
> "buf[i]" is not a multiple of 4 -- and this depends not only on the
> value of "i", but on the actual starting address of "buf"...something
> that the compiler DOES NOT KNOW.  That depends on where the linker
> puts it (or, if it were allocated dynamically, rather than as you show
> it, it would depend on where the memory allocation routine found space
> for it).
> 
> If you try out the above properly aligned structure definition with a
> "cast" to a char buffer of unknown alignment, you will find that just
> about every compiler will fail to produce the "right" code to work in
> every circumstance, and that the use of "proper alignment" in the
> structure definition will fool it into thinking there is no cause for
> even so much as a warning to you.
> 
> This, I think, is the downfall of your original example.  You declared
> some "auto" or static ints (x[4]), can't tell which from the code
> excerpt.  The compiler knew enough to force their alignment on the
> stack or in memory to an appropriate boundary to make them accessible
> with a normal int-aligned addressing mode.  However, the compiler had
> no reason to care a bit about the alignment of "char buf[]", since it
> expects you to be using it to hold chars (silly compiler).  But, then
> you threw the compiler a curve by using an int* to access an arbitrary
> spot in a  byte-aligned buffer and assign this to one of those x[i]'s.
>  What's a poor compiler to do?
> 
> You owe the compiler an apology.
> 
> cordeg
> 
> 
> --- In lpc2000@yahoogroups.com, "dsidlauskas1" <dsidlauskas@> wrote:
> >
> > ints are not always word aligned. For example:
> > 
> > #pragma packed(1)
> > struct eg
> >      {
> >      char x;
> >      int y;
> >      char z;
> >      int w;
> >      }test;
> > 
> > One of the integers in this structure is not word word aligned and yet
> > reference to the non word aligned integer works fine, as should
> > 
> > int x, *ip;
> > ip = &test.w;
> > x = *ip;
> > 
> > 
> > --- In lpc2000@yahoogroups.com, "fordp2002" <SimonEllwood@> wrote:
> > >
> > > By casting buf to an int you have instructed the compiler NOT to
treat
> > > it as a byte.
> > > 
> > > It is beholden on you the software engineer to ensure whatever you
> > > cast is compatible with what you cast it too. In this case you are
> > > saying that &buf[i] is word aligned, which will be only true for one
> > > in four cases of i. If the compiler aligns the start of buf to a
word
> > > bondary which will happen under some cases &buf[0] will be the only
> > > legal cast.
> > > 
> > > FordP
> > > 
> > > 
> > > --- 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.