Wojtek Lerch wrote:
> On 08/11/2010 6:08 PM, Johannes Schaub (litb) wrote:
>> Wojtek Lerch wrote:
>>> "Marcin Grzegorczyk"<> wrote in message
>>> news:ib9jl4$mec$...
>>>> Wojtek Lerch wrote:
>>>>> "Wojtek Lerch"<> wrote in message
>>>>> news:...
>>>>>> "Marcin Grzegorczyk"<> wrote in message
>>>>>> news:ib4h3f$g0j$...
>>>>>>> [...] GCC, for example, allows FAM
>>>>>>> initialization as an extension. [...]
>>>>>>
>>>>>> What does sizeof return when applied to the name of such object?
>>>>>
>>>>> To answer my own question, sizeof does not include the FAM. The
>>>>> analogy with arrays of unknown size is bogus.
>>>>
>>>> The analogy was supposed to apply to how a compiler determines the size
>>>> of an object, and my point was that there are situations where the size
>>>> is known only after the initialization has been parsed.
>>>
>>> But even that analogy is not very good: in the case of normal arrays,
>>> the initializer determines the *type* of the object, and then the size
>>> follows
>>> from the type in the usual way. In the case of a structure with a FAM,
>>> the type of the object is the struct, and the size of that type does not
>>> include
>>> the array (or at least not necessarily all of it). Since the size of
>>> the object, as reported by sizeof, doesn't include the array either, one
>>> could argue that the array doesn't really belong to the declared object,
>>> but to a
>>> larger unnamed object that contains both the struct and the array.
>>> (That's, BTW, more or less how this extension is explained by GCC
>>> documentation.)
>>
>> I think the C99 Standard [...]
>
> You do realize that the discussion was not about a standard feature, but
> a GCC extension, right?
>
I wanted to show that according to the C99 Standard (in my interpretation),
it doesn't have to be an extension. I'm sorry if i slightly missed the
intention of this thread.
>> [...] makes no difference between non-subobjects and
>> subobjects. It just says
>>
>> "Each brace-enclosed initializer list has an associated current object.
>> When no designations are present, subobjects of the current object are
>> initialized in order according to the type of the current object [...]"
>
> Um... It says "subobjects" right there, and doesn't mention
> non-subobjects. Is that not a difference? 
>
It says "subobjects ... are initialized ..." here, and in the following text
it says "If an array of unknown size is initialized...". These two
paragraphs fit perfectly together, I think.
>> "If an array of unknown size is initialized, its size is determined by
>> the largest indexed element with an explicit initializer. At the end of
>> its initializer list, the array no longer has incomplete type."
>>
>> I think this states that the FAM's size is correctly determined by that
>> procedure.
>
> Does it? What is the type of the FAM before and after the initializer?
>
I'm not really sure how I should interpret this wording. The meaning that is
compatible with my reading is: The effective type of the object is an array
type with that many initializers.
That does not, in my reading, necessarily mean that any expression refering
to it (like, a member access) actually has that type too. The aliasing rules
allow an object whose effective type is "T[N]" be accessed by an lvalue of
type "T[]".
>>>> This does not
>>>> have to do anything with sizeof.
>>>
>>> Other than the fact that sizeof is supposed to report the size of the
>>> object. 
>>
>> It can't report the size of objects, because that is only known at
>> runtime. It therefor only reports "from the type of the operand.".
>
> Right. But does that mean that an object declared using the GCC
> extension is bigger than its type, or does it mean that the declared
> object is the size of its type but is a subobject of a bigger, unnamed
> object that the compiler allocates to accommodate for the initialized
> FAM? The documentation is not completely clear on that, and of course
> C99 is silent on the matter.
In the following the object referenced is also larger than the effective
type of a sub-portion of it (at least twice as large, actually).
int *p = malloc(sizeof *p * 2);
*p = 0; // modify the first half only
In the case of "int[]" vs "int[N]", the "int[]" doesn't make any assumption
on the type of the object referenced, and doesn't need to do that either: As
long as you don't invoke sizeof on it, you can perfectly well use such an
expression to modify array elements.
I *think* that any object of size N bytes is also N*(N+1)/2 objects, each
being different because the start address or size of them is different. What
object is addressed depends on the lvalue you use (which in turn determines
the address and effective type, i.e size). Not sure what object is accessed
by an "T[]" expression though - I could imagine that the size-N object is
addressed. Tho if you have any insights, please lemme hear!