Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #94711 > unrolled thread

C language declaration "bugs"

Started byThiago Adams <thiago.adams@gmail.com>
First post2016-10-11 05:17 -0700
Last post2016-10-11 14:14 +0100
Articles 9 — 4 participants

Back to article view | Back to comp.lang.c


Contents

  C language declaration "bugs" Thiago Adams <thiago.adams@gmail.com> - 2016-10-11 05:17 -0700
    Re: C language declaration "bugs" Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-11 13:58 +0100
      Re: C language declaration "bugs" Thiago Adams <thiago.adams@gmail.com> - 2016-10-11 06:47 -0700
        Re: C language declaration "bugs" Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-11 15:03 +0100
          Re: C language declaration "bugs" Thiago Adams <thiago.adams@gmail.com> - 2016-10-11 07:41 -0700
            Re: C language declaration "bugs" BartC <bc@freeuk.com> - 2016-10-11 16:31 +0100
          Re: C language declaration "bugs" Keith Thompson <kst-u@mib.org> - 2016-10-11 10:01 -0700
            Re: C language declaration "bugs" Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-11 19:10 +0100
    Re: C language declaration "bugs" BartC <bc@freeuk.com> - 2016-10-11 14:14 +0100

#94711 — C language declaration "bugs"

FromThiago Adams <thiago.adams@gmail.com>
Date2016-10-11 05:17 -0700
SubjectC language declaration "bugs"
Message-ID<90bf0ba6-5094-4551-8cc0-c60214b14362@googlegroups.com>
Off course this is not a bug. 
But I think it s strange that I cannot use the same 
syntax for declarations in structs and functions.

For instance:

struct X
{
  int * a[]; //ERROR
  int b[]; //ERROR
};

void f(int * a[]) { } //Ok
void f2(int b[]) { } //Ok

I was planning to use this syntax to document that for instance

struct X{
int b[];
}

b is a pointer to many ints.

and 

int * b; would be used to document a pointer to just one int

(also a tip for static analysis)



typedef int PointerToIntegers[];

typedef int* PointerToIntegers2;
 
struct X
{
  PointerToIntegers b; //ERROR 
  PointerToIntegers2 b2; //OK
};
 

when I do out of function scope

//warning: array 'i' assumed to have one element 
int i[];

So here is one more language suggestion:

make empty array syntax the same of  "pointer" syntax.


int i[]; the same of int *i;


[toc] | [next] | [standalone]


#94714

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-10-11 13:58 +0100
Message-ID<87d1j7avp8.fsf@bsb.me.uk>
In reply to#94711
Thiago Adams <thiago.adams@gmail.com> writes:

> Off course this is not a bug. 
> But I think it s strange that I cannot use the same 
> syntax for declarations in structs and functions.
>
> For instance:
>
> struct X
> {
>   int * a[]; //ERROR
>   int b[]; //ERROR
> };

The second one is not an error -- it's a flexible array member (or would
be if there were at least one valid struct member preceding it).  It
does not say what you want, I agree, but it's not an error.

> void f(int * a[]) { } //Ok
> void f2(int b[]) { } //Ok

Another way of looking at is that it's a shame C permits the special
case of empty []s to mean * in a parameter declaration.  It's a
hang-over from very early C and is no more than an anomaly.  What's
more, you can even put a number in there for no purpose at all.

But now the []s in that position have acquired a new set of meanings:

  void f(int n, int a[n]);       // variably modified parameter
  void f(int n, int a[*]);       // alternative for (prototypes only)
  void f(int a[static 3]);       // pointer to at least 3 ints
  void f(int a[const static 3]); // const pointer to at least 3 ints

and more besides.

The fact that type qualifiers (like const) in that position modify the
pointer is reasonable (since the pointed-to type can be qualified
anyway) but unfortunate.  I.e.

  void f(int a[const]);

is just a silly way to write

  void f(int *const s);

<snip>
> when I do out of function scope
>
> //warning: array 'i' assumed to have one element 
> int i[];
>
> So here is one more language suggestion:
>
> make empty array syntax the same of  "pointer" syntax.
>
> int i[]; the same of int *i;

C's desire not to break existing code both its strength and its
weakness.  It has resulted in all sorts of oddities because the ISO C
committee is very conservative about changes to the meaning of currently
valid code.  Some would say it's been too conservative and some would
say not conservative enough.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#94718

FromThiago Adams <thiago.adams@gmail.com>
Date2016-10-11 06:47 -0700
Message-ID<b4976e0d-cedb-4721-a261-d3597eb43b97@googlegroups.com>
In reply to#94714
On Tuesday, October 11, 2016 at 9:58:52 AM UTC-3, Ben Bacarisse wrote:
> Thiago writes:

> But now the []s in that position have acquired a new set of meanings:
> 
>   void f(int n, int a[n]);       // variably modified parameter


void f(int n, int a[n]);

This one is a tip? where n is the size?

I can't find any options to express dynamic arrays in structs.

The problem is not worst because it happens only at first level of abstraction and the name is generally in plural.


typedef struct 
{
   int *itens; 
   int size;
} Array;

struct Other
{
 Array itens; //ok
}

I think the static analyzer can search for 's' at the end of the name. :)

I agree with Bart as well. I didn't see the ambiguous cases before. thanks

[toc] | [prev] | [next] | [standalone]


#94719

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-10-11 15:03 +0100
Message-ID<87zimb9e5b.fsf@bsb.me.uk>
In reply to#94718
Thiago Adams <thiago.adams@gmail.com> writes:

> On Tuesday, October 11, 2016 at 9:58:52 AM UTC-3, Ben Bacarisse wrote:
>> Thiago writes:
>
>> But now the []s in that position have acquired a new set of meanings:
>> 
>>   void f(int n, int a[n]);       // variably modified parameter
>
>
> void f(int n, int a[n]);
>
> This one is a tip? where n is the size?

Yes, because the "first level" of []s always just mean "pointer" so the
n is really only for documentary purposes.  A proper variably modified
array parameter would have []s where the size matters:

  void f(int n, int (*a)[n]);
  void f(int m, int n, int a[m][n]);

Note that the type of a is the same in both of the functions.  Here,
sizeof a will give the size of a pointer, but sizeof a[0] will depend on
n.

> I can't find any options to express dynamic arrays in structs.

No, you can't, other than the "struct hack" of putting a flexible array
member (i.e. an incomplete array declaration) as the last member.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#94721

FromThiago Adams <thiago.adams@gmail.com>
Date2016-10-11 07:41 -0700
Message-ID<ad00e1c6-3c8b-48f5-b9da-d6f53d159cde@googlegroups.com>
In reply to#94719
On Tuesday, October 11, 2016 at 11:03:21 AM UTC-3, Ben Bacarisse wrote:
> Thiago Adams writes:

> > I can't find any options to express dynamic arrays in structs.
> 
> No, you can't, other than the "struct hack" of putting a flexible array
> member (i.e. an incomplete array declaration) as the last member.


Just to add one more case :

int [] F(); 

Function returning many int's.

So..when we see

Type* F(); //F singular (GetItem) pointer to one
Type* F(); //F plural (GetItems) pointer to many

[toc] | [prev] | [next] | [standalone]


#94723

FromBartC <bc@freeuk.com>
Date2016-10-11 16:31 +0100
Message-ID<ntj0jo$d21$1@dont-email.me>
In reply to#94721
On 11/10/2016 15:41, Thiago Adams wrote:
> On Tuesday, October 11, 2016 at 11:03:21 AM UTC-3, Ben Bacarisse wrote:
>> Thiago Adams writes:
>
>>> I can't find any options to express dynamic arrays in structs.
>>
>> No, you can't, other than the "struct hack" of putting a flexible array
>> member (i.e. an incomplete array declaration) as the last member.
>
>
> Just to add one more case :
>
> int [] F();
>
> Function returning many int's.
>
> So..when we see
>
> Type* F(); //F singular (GetItem) pointer to one
> Type* F(); //F plural (GetItems) pointer to many

It might be a good idea to have a way of designating a pointer to 
multple elements. But [] is overloaded already.

C however already has a way of doing that:

int (*F())[];    // or:

int (*F())[] {...}

(The last example might look odd, as you don't often see [] just before 
the { of a function body.)

This says the function returns a pointer to an array; pretty much what 
we're after.

Except that hardly anyone who programs in C likes using pointers to 
actual arrays (not in this group anyway). Everyone prefers pointers to 
elements.

Partly, that's because of the awful syntax involved in declaring such 
types and using them.

So, if you need to invent new syntax, it needs to be simpler than array 
syntax. You also have to decide, when p is regular pointer, and q points 
to a multiple, whether p[i] or (p+i) should still be allowed.

For compatibility reasons, it would have to be. But then that means 
three kinds of pointer would be needed:

* Standard C pointer that can target single or multiple objects
* Pointers to single objects
* Pointers to multiple objects

Otherwise there would be little point.

-- 
Bartc


[toc] | [prev] | [next] | [standalone]


#94732

FromKeith Thompson <kst-u@mib.org>
Date2016-10-11 10:01 -0700
Message-ID<ln60oyom5l.fsf@kst-u.example.com>
In reply to#94719
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Thiago Adams <thiago.adams@gmail.com> writes:
[...]
>> I can't find any options to express dynamic arrays in structs.
>
> No, you can't, other than the "struct hack" of putting a flexible array
> member (i.e. an incomplete array declaration) as the last member.

I think the term "struct hack" generally refers to the old technique of
defining an array member of length 0 or 1 at the end of a structure and
treating it as a longer array.  Flexible array members, added in C99,
were intended to *replace* the struct hack.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#94735

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-10-11 19:10 +0100
Message-ID<87twciah95.fsf@bsb.me.uk>
In reply to#94732
Keith Thompson <kst-u@mib.org> writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>> Thiago Adams <thiago.adams@gmail.com> writes:
> [...]
>>> I can't find any options to express dynamic arrays in structs.
>>
>> No, you can't, other than the "struct hack" of putting a flexible array
>> member (i.e. an incomplete array declaration) as the last member.
>
> I think the term "struct hack" generally refers to the old technique of
> defining an array member of length 0 or 1 at the end of a structure and
> treating it as a longer array.  Flexible array members, added in C99,
> were intended to *replace* the struct hack.

Yes, it does.  I meant to imply that it had been sanctioned with the new
syntax but I don't think that came out.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#94715

FromBartC <bc@freeuk.com>
Date2016-10-11 14:14 +0100
Message-ID<ntioih$f8k$1@dont-email.me>
In reply to#94711
On 11/10/2016 13:17, Thiago Adams wrote:

> But I think it s strange that I cannot use the same
> syntax for declarations in structs and functions.
>
> For instance:
>
> struct X
> {
>   int * a[]; //ERROR
>   int b[]; //ERROR
> };
>
> void f(int * a[]) { } //Ok
> void f2(int b[]) { } //Ok
>
> I was planning to use this syntax to document that for instance
>
> struct X{
> int b[];
> }
>
> b is a pointer to many ints.
>
> and
>
> int * b; would be used to document a pointer to just one int
>
> (also a tip for static analysis)

You've just discovered that C type declarations are a mess. As well as 
being context sensitive.

> when I do out of function scope
>
> //warning: array 'i' assumed to have one element
> int i[];
>
> So here is one more language suggestion:
>
> make empty array syntax the same of  "pointer" syntax.
>
>
> int i[]; the same of int *i;

That's going to be a problem because empty bounds are often used like this:

  int i[] = {10,20,30,40};

The bounds are now determined by the compiler (4 in this example). 
Requiring even that to be implemented by pointer will cause 
difficulties. And a mismatch between the above and:

  int j[4] = {10,20,30,40};

Here, i=0 would be legal, but not j=0;

It will also cause a mismatch (a serious one this time) when j is 
declared elsewhere as:

  extern int j[];

Here, you can't put in the bounds as you don't know what they are. 
(You'd have to put in a misleading dummy length.)

Also, in a function:

  void fn(int (*A)[]);

A has type 'pointer to unbounded array of int'. But you want [] to add 
an extra pointer to result in ... ?


-- 
Bartc



>
>
>

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web