[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Quesition about Lisp_Vector
From: |
Ken Raeburn |
Subject: |
Re: Quesition about Lisp_Vector |
Date: |
Fri, 11 Nov 2011 04:01:27 -0500 |
On Nov 11, 2011, at 01:29, Qiang Guo wrote:
> Hi, I'm new to devel aspect of Emacs. And I'm having a problem reading
> Emacs source code: in the definition of Lisp_Vector
> struct Lisp_Vector
> {
> EMACS_UINT size;
> struct Lisp_Vector *next;
> Lisp_Object contents[1];
> };
>
> why contents's size is fixed ? And later when actually allocating space
This is a common idiom for handling a structure with a variable-sized array at
the end. The latest spec for the C language has support built in for a
slightly different mechanism, but this scheme used above has been a common way
to get around the absence of variable-sized arrays in structures in traditional
C for a long time, and it works on most if not all C compilers.
>
> nbytes = sizeof *p + (len - 1) * sizeof p->contents[0];
>
> I don't understand how this nbytes is calculated. why only (len-1)
> contents[0] ? and how can the size of an array be changed ?
The "len-1" means we want an array with "len" elements in it, but the first
element is covered by "sizeof *p" because "struct Lisp_Vector" includes one
array element already. If you use an index greater than zero, the value
referenced may be stored in extra padding space at the end of the structure, if
there is any, or in the additional space we allocated past the end of the
structure. If you think about it, it really doesn't matter which; all that
matters is that for array indexes less than "len", we've allocated at least
enough extra space.
If you use a compiler or interpreter designed to run C code with extensive,
very pedantic run-time checks, it *might* notice if the array index used is
greater than 0 and warn you. But under pretty much any normal compiler this
should just work without any complaint.
Ken