>>>> "KJ" == Kyle Jones
<kyle_jones(a)wonderworks.com> writes:
KJ> Olivier Galibert writes:
> On Tue, Jan 25, 2000 at 06:47:48PM -0800, Martin Buchholz wrote:
> > I suggest the following as being more intuitive, more maintainable,
> > and also being more correct. You are making the non-portable
> > assumption that the compiler lays out structs like an array. In fact,
> > the compiler can order key and value any way it likes. You did call
> > it the _portable_ dumper.
>
> If you do such a "fix", do it everywhere. There are a lot of places
> where I do this assumption.
KJ> I remeber reviewing some code that made this assumption and doing
KJ> some reading of the H&S C reference. I came to the conclusion
KJ> that treating a struct like an array was portable. I'm away from
KJ> my books at the moment so I can't quote anything yet. But I'm
KJ> curious, Martin, why you think it isn't portable?
Sorry, it would be more correct to argue that we can portably rely on
the ORDER of elements in a struct, but not the presence of padding.
For example, the compiler might decide to compile
struct cons
{
Lisp_Object car;
Lisp_Object cdr;
}
as
struct cons
{
4-byte car;
4-byte pad;
4-byte cdr;
4-byte pad;
}
because, for example, the hardware is 64-bit, but the OS is still
32-bit, and pointers are more efficient when 64-bit aligned.
In practice, today, nobody is actually going to do that. Still, it's
nice to code to the ANSI C standard when possible. No one used to do
alias analysis either (except xlc...).
OG> On Tue, Jan 25, 2000 at 06:47:48PM -0800, Martin Buchholz wrote:
OG> If you do such a "fix", do it everywhere. There are a lot of places
OG> where I do this assumption. I do others, btw, like the fact that all
OG> pointers are of the same size.
OG> In particular, I'm interessed in how you're going to handle that one:
OG> #define BUFFER_SLOTS_SIZE (offsetof (struct buffer, BUFFER_SLOTS_LAST_NAME) -
offsetof (struct buffer, BUFFER_SLOTS_FIRST_NAME) + sizeof (Lisp_Object))
OG> #define BUFFER_SLOTS_COUNT (BUFFER_SLOTS_SIZE / sizeof (Lisp_Object))
This code has the same portability `problem'. The `correct' thing is
to have the buffer slots in an array of Lisp_Object, and then use
countof to portably count them. If something is being used like an
array, maybe it should _be_ an array. If you claim this is not worth
fixing, I might agree with you - after all this is old code. But
you're adding new code.
But a more fundamental reason is maintainability.
Pretend you're going to delete a member from a Lisp Object type
struct. You do a global grep for the member name, and remove those.
And then you get strange crashes because you didn't change a `6' to a
`5'.
There are times when I argue for verboseness in code. This is one of
them. Although your code works, it is not as `clean' as it could be.
However, don't consider that you have to change this. There are lots
of real bugs to fix. But I might, whenever I hack on this. I
assume I have your permission.
Pedantically yours,
Martin