Re: [9fans] C compiler question

2009-07-15 Thread robert wilson
erik quanstrom wrote:
 assuming that pointers to incomplete types are
 themselves incomplete, and you haven't cited
 chapter and verse showing they are, i read that paragraph
 as saying that what plan 9 libraries do would be
 illegal, and therefore if we follow the standard,
 we'd need to remove Incomplete*s and replace
 them with void*s.
 
 if i'm wrong, can you explain how?

 The void type comprises an empty set of values; it is an incomplete
type that cannot be completed.

if a pointer to an incomplete type is incomplete, then void* is
incomplete, too. as far as i can tell, the standard would allow an
implementation where pointers vary in size and the sizes of pointers
can't be determined at compile-time, but that would be insane.



Re: [9fans] C compiler question

2009-07-15 Thread Ethan Grammatikidis
On Tue, 14 Jul 2009 12:45:56 -0700
Russ Cox r...@swtch.com wrote:

 enough.
 
 there was a bug, plain and simple.
 
 struct T {
   struct S s;
 };
 
 is not valid.  never was, never will be.
 fix the compiler already.

Newbie question: Does this statement apply to any struct S (meaning you can 
never have a struct as member of another struct), or does it only apply in 
cases where the structure of S is not known at that point?


-- 
Ethan Grammatikidis

Those who are slower at parsing information must
necessarily be faster at problem-solving.



Re: [9fans] C compiler question

2009-07-15 Thread erik quanstrom
 Newbie question: Does this statement apply to any struct S (meaning you can 
 never have a struct as member of another struct), or does it only apply in 
 cases where the structure of S is not known at that point?

the latter.

- erik



Re: [9fans] C compiler question

2009-07-14 Thread Adriano Verardo

erik quanstrom wrote:


Yes, but in my example - sorry - NeverDefined doesn't mean declared and
defined elsewhere (or not) but not declared .and. not defined.
   



true enough.  the patch i sent still rejects your construct.
i'd still be interested to hear a perspective of someone with
more experience with the c compiler.

- erik



 

The point is how to compute the offset(s) of the last field at compile / 
run time.

8c should reject not defined (named only) types, as *nix compilers do.

I think that it could be possible to allow the expansion of structs by a 
final struct field
but this, in my opinion,  would imply portability problems and in 
general more error

prone code.

I prefer to have only the tricky but standard  char  x[0] tails.


Your patch will be included in the next distribution CD ?


adriano



Re: [9fans] C compiler question

2009-07-14 Thread erik quanstrom
 The point is how to compute the offset(s) of the last field at compile / 
 run time.

the offset of the last field is not in question.  i believe you mean the size?

 8c should reject not defined (named only) types, as *nix compilers do.

yes.

 
 I prefer to have only the tricky but standard  char  x[0] tails.

i'd prefer not to have them, either.  but it's too late for that.

 Your patch will be included in the next distribution CD ?

no.  i haven't submitted it yet.

- erik



Re: [9fans] C compiler question

2009-07-14 Thread Adriano Verardo

erik quanstrom wrote:
The point is how to compute the offset(s) of the last field at compile / 
run time.



the offset of the last field is not in question.  i believe you mean the size?
  

It's really the same info.

struct
{
 . // total sizeof = 100
   int B[..];
}A;

offset(B) = 100,  (A.B[7]) == address(A) + 100 + 7*sizeof(int).
The compiler accept the dirty but legal expression  A.B[-3]  because it 
can compute
the address (or the offset with respect the beginnig of A) of the B 
-3 cell.


But in this case

struct
{
 . // total sizeof = 100
   struct B B;
}A;

with B declared (just named), how 8c could determined the address of A.B.x ?
To accept the above definition of A, say in a global .h, means that every .c
should include the definition of B.
They could be - legally - different, so generating different offsets of 
x with respect A

in the same program.



I prefer to have only the tricky but standard  char  x[0] tails.



i'd prefer not to have them, either.  but it's too late for that.

  

:-)   And what about

char x[...]  and   x[2] == 2[x]:-)  :-)

Your patch will be included in the next distribution CD ?



no.  i haven't submitted it yet.

- erik

adriano





Re: [9fans] C compiler question

2009-07-14 Thread erik quanstrom
 erik quanstrom wrote:
  The point is how to compute the offset(s) of the last field at compile / 
  run time.
  
 
  the offset of the last field is not in question.  i believe you mean the 
  size?

 It's really the same info.

it is not.  the size and offset are different things.

 offset(B) = 100,  (A.B[7]) == address(A) + 100 + 7*sizeof(int).
 The compiler accept the dirty but legal expression  A.B[-3]  because it 
 can compute
 the address (or the offset with respect the beginnig of A) of the B 
 -3 cell.

this is completely beside the point and furthermore the sizeof A.B never
enters into the picture.

- erik



Re: [9fans] C compiler question

2009-07-14 Thread Roman V Shaposhnik
On Mon, 2009-07-13 at 23:14 -0400, erik quanstrom wrote:
  Yes, but in my example - sorry - NeverDefined doesn't mean declared and
  defined elsewhere (or not) but not declared .and. not defined.
 
 true enough.  the patch i sent still rejects your construct.
 i'd still be interested to hear a perspective of someone with
 more experience with the c compiler.

rejecting the struct seems like the right thing to do as per
ISO/IEC 9899:1999 (http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf)
sec. 6.7.2.1 para. 2

A structure or union shall not contain a member with incomplete or function 
type (hence,
a structure shall not contain an instance of itself, but may contain a pointer 
to an instance
of itself), except that the last member of a structure with more than one named 
member
may have incomplete array type; such a structure (and any union containing, 
possibly
recursively, a member that is such a structure) shall not be a member of a 
structure or an
element of an array.

Thanks,
Roman.




Re: [9fans] C compiler question

2009-07-14 Thread erik quanstrom
 rejecting the struct seems like the right thing to do as per
 ISO/IEC 9899:1999 (http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf)
 sec. 6.7.2.1 para. 2
 
 A structure or union shall not contain a member with incomplete or function 
 type (hence,
 a structure shall not contain an instance of itself, but may contain a 
 pointer to an instance
 of itself), except that the last member of a structure with more than one 
 named member
 may have incomplete array type; such a structure (and any union containing, 
 possibly
 recursively, a member that is such a structure) shall not be a member of a 
 structure or an
 element of an array.

you're implying that the point of the plan 9 compilers
is to toe the c99 line.

also, a pointer to an incomplete type is used
in many places in plan 9 libraries.

- erik



Re: [9fans] C compiler question

2009-07-14 Thread Roman V Shaposhnik
On Tue, 2009-07-14 at 13:46 -0400, erik quanstrom wrote:
  rejecting the struct seems like the right thing to do as per
  ISO/IEC 9899:1999 
  (http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf)
  sec. 6.7.2.1 para. 2
  
  A structure or union shall not contain a member with incomplete or 
  function type (hence,
  a structure shall not contain an instance of itself, but may contain a 
  pointer to an instance
  of itself), except that the last member of a structure with more than one 
  named member
  may have incomplete array type; such a structure (and any union containing, 
  possibly
  recursively, a member that is such a structure) shall not be a member of a 
  structure or an
  element of an array.
 
 you're implying that the point of the plan 9 compilers
 is to toe the c99 line.

For the dirty corner of any language one is usually better off with
a written formal standard. Now, since Plan9 doesn't have such a
document, relying on a work done by c99 committee would seem like
a wise thing to do. 

And it is not like we are talking about C++ ISO standard here, the
C99 is actually quite beautiful (except may be a couple of places
like compound literals, and stuff).

What's your problem with such an approach? 

 also, a pointer to an incomplete type is used
 in many places in plan 9 libraries.

The above paragraph has nothing to do with pointers to incomplete types
(except for a clarification). Why are you bringing this up?

Thanks,
Roman.




Re: [9fans] C compiler question

2009-07-14 Thread erik quanstrom
 For the dirty corner of any language one is usually better off with
 a written formal standard. Now, since Plan9 doesn't have such a
 document, relying on a work done by c99 committee would seem like
 a wise thing to do. 
 
 And it is not like we are talking about C++ ISO standard here, the
 C99 is actually quite beautiful (except may be a couple of places
 like compound literals, and stuff).

 What's your problem with such an approach?

only the part where i abdicate my ability to think to
a committee.  i'm difficult that way.

  also, a pointer to an incomplete type is used
  in many places in plan 9 libraries.
 
 The above paragraph has nothing to do with pointers to incomplete types
 (except for a clarification). Why are you bringing this up?

assuming that pointers to incomplete types are
themselves incomplete, and you haven't cited
chapter and verse showing they are, i read that paragraph
as saying that what plan 9 libraries do would be
illegal, and therefore if we follow the standard,
we'd need to remove Incomplete*s and replace
them with void*s.

if i'm wrong, can you explain how?

- erik



Re: [9fans] C compiler question

2009-07-14 Thread Russ Cox
enough.

there was a bug, plain and simple.

struct T {
  struct S s;
};

is not valid.  never was, never will be.
fix the compiler already.

russ



Re: [9fans] C compiler question

2009-07-13 Thread Adriano Verardo

erik quanstrom wrote:


8c silently accept the above definition and sizeof(U) is 100.  ???
The sources which include the definition of NeverDefined are
regularly compiled too and sizeof(U) = 100 + sizeof(NeverDefined).

   



i think the issue is that there isn't currently a distinction
between this

typedef struct A A;
struct A {
int expand[0];
};

which is perfectly legal and this

typedef struct U U;
typedef struct A A;
struct A {
U;
};
 


Yes, but in my example - sorry - NeverDefined doesn't mean declared and
defined elsewhere (or not) but not declared .and. not defined.

No doubt this should be a fatal error, but 8c accepts.
What's my mistake ?

adriano



Re: [9fans] C compiler question

2009-07-13 Thread erik quanstrom
 Yes, but in my example - sorry - NeverDefined doesn't mean declared and
 defined elsewhere (or not) but not declared .and. not defined.

true enough.  the patch i sent still rejects your construct.
i'd still be interested to hear a perspective of someone with
more experience with the c compiler.

- erik



Re: [9fans] C compiler question

2009-07-13 Thread Russ Cox
 Yes, but in my example - sorry - NeverDefined doesn't mean declared and
 defined elsewhere (or not) but not declared .and. not defined.

no and yes.

union U
{
  struct
  {
struct NeverDefined  nf;  //  Unknown, definition
not #included
  } S1
};

declares a struct named NeverDefined just by mentioning it.
the compiler should reject the use because NeverDefined
is not defined.  it's just a bug.  i don't have a copy of the
compiler to play with but erik's patch seems fine.

russ



Re: [9fans] C compiler question

2009-07-12 Thread erik quanstrom
 8c silently accept the above definition and sizeof(U) is 100.  ???
 The sources which include the definition of NeverDefined are
 regularly compiled too and sizeof(U) = 100 + sizeof(NeverDefined).
 

i think the issue is that there isn't currently a distinction
between this

typedef struct A A;
struct A {
int expand[0];
};

which is perfectly legal and this

typedef struct U U;
typedef struct A A;
struct A {
U;
};

which might be allowed, but i can't find any references
that say it is.  the argument for having expandable
structures would be it would allow something like this

typedef struct Priv Priv;
typedef struct Pub Pub;
struct Pub {
...
Priv;
};
#pragma incomplete Pub

Pub *pubfn(void);

but i don't see any such uses in /sys/include.
this change will generate a diagnostic for your code,
but be careful.  this is a corner of c, and what seems
intuitively correct in the corners can often be wrong.

- erik

; diff -c dcl.c `{yesterday -n2 dcl.c}
dcl.c:541,547 - /n/dump/2009/0710/sys/src/cmd/cc/dcl.c:541,547
l-offset = o;
} else {
if(l-width = 0)
-   if(l-down != T || l-width  0)
+   if(l-down != T)
if(l-sym)
diag(Z, incomplete structure 
element: %s,
l-sym-name);