From: bbobak@undergrad.math.waterloo.edu (Brad Bobak)
Subject: Re: Is this allowed in C?
Organization: University of Waterloo
Date: Fri, 22 Jan 1993 16:16:07 GMT

In article <1993Jan22.012502.5241@nntpd.lkg.dec.com>, diamond@jit533.jit.dec.com (Norman Diamond) writes:
> In article <C17p4n.Dx8@undergrad.math.waterloo.edu> bbobak@undergrad.math.waterloo.edu (Brad Bobak) writes:
> 
> Well, I noticed a few years ago that most of the practical-oriented stuff
> moved to the new Computer Engineering department, but surely there should
> still be some consultants or TAs that could help with this kind of problem?
> 
> > I was wondering if the following was valid in C.
> > struct astruct { int something; int something_else; } blah;
> > main() {
> >    char *store;
> >    store = malloc(sizeof(blah));
> >    memcpy(store, &blah, sizeof(blah));
> >    /* how about this? */
> >    {
> >        int another_int = 5;
> >        memcpy(&((struct astruct *)store)->something, &another_int,
> >               sizeof(int));
> >    }
> 
> The C standard guarantees that whenever malloc() succeeds (which you forgot
> to check), the value will point to storage suitably aligned for everything,
> including structs.  So (struct astruct *)store can indeed be used as a pointer
> to a struct astruct.
 Yes, I didn't check malloc because this was just an example. But I always
  do.
 My example wasn't clear on what I really meant. Lets change the malloc()
  line to:
 store = malloc(sizeof(blah)+3) + 3;
 /* so that store isn't guaranteed to be aligned for anything, except
  * chars (is this true?)
  */
> 
> Pedantically, the standard forgot to say that when pointers to objects are
> converted to pointers to void, it should be possible to use the pointers to
> void in calls to memcpy() and other such functions.  However, I don't think
> any implementor would dare to play games with this.
> 
> > and something else similar:
> >#define CHAR_MASK ((1 << BITS_IN_CHAR) - 1)
> >/* I realize this might fail if sizeof(int) == sizeof(char), if [...] */
> 
> This is indeed possible.  Why not use UCHAR_MAX?
 No reason. I will do this.
> 
> > main() {
> >    int val;
> >    char *store;
> >    int ct;
> >    store = malloc(sizeof(val));
> >    for (ct=0; ct<sizeof(int); ct++)
> >        store[ct] = (val >> (ct * BITS_IN_CHAR)) & CHAR_MASK;
> >    for (val=0, ct=0; ct<sizeof(int); ct++)
> >        val |= store[ct] << (ct * BITS_IN_CHAR);
> 
> Looks reasonable to me.
> 
> > The reason I'm doing it this way is that I've made a memory allocation
> >  library. And some systems require special alignment of data. So to
> >  archive something, I have to copy it to a char array.
> 
> You mean that you might write the archive to a file and read it back on
> another system?  What happens if you write the file on a system with
> 8-bit chars and read it back on a system with 9-bit chars?
 No, actually I mean to just archive something in memory.
 When sending data across the network, I convert everything to bitstreams
  and use a fixed size for chars/ints (if a certain architecture can't
  support that size, my library will say so)
> 
> >This next question probably has surfaced a few times, but is there any way
> >to guarantee the right alignment of arbritary data on various architectures?
> 
> Whenever you declare a variable (an int or a struct of some sort or whatever)
> the implementation has to be able to handle it.  If the implementation fails
> to align it properly, then the implementation has to work it out somehow,
> generating extra slow code if necessary.  And when malloc() succeeds, it
> returns a pointer that you're allowed to use for any type of object.  However,
> if you want some implementation to provide alignments that will work for some
> different implementation, you're usually out of luck.
 I thought this would be the case. Guess I'll have to stick to the slow way.
> --
> Norman Diamond                diamond@jit.dec.com
> If this were the company's opinion, I wouldn't be allowed to post it.
> Pardon me?  Or do I have to commit a crime first?

 Sorry about the length of the article, but I don't really see what I can
  cut out.