home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.std.c
- Path: sparky!uunet!elroy.jpl.nasa.gov!ames!haven.umd.edu!decuac!pa.dec.com!engage.pko.dec.com!nntpd.lkg.dec.com!jit533.jit.dec.com!diamond
- From: diamond@jit533.jit.dec.com (Norman Diamond)
- Subject: Re: Is this allowed in C?
- Message-ID: <1993Jan22.012502.5241@nntpd.lkg.dec.com>
- Sender: usenet@nntpd.lkg.dec.com (USENET News System)
- Reply-To: diamond@jit.dec.com (Norman Diamond)
- Organization: Digital Equipment Corporation Japan , Tokyo
- References: <C17p4n.Dx8@undergrad.math.waterloo.edu>
- Date: Fri, 22 Jan 1993 01:25:02 GMT
- Lines: 69
-
- 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.
-
- 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?
-
- > 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?
-
- >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.
- --
- 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?
-