C2 forum

General Category => Ideas => Topic started by: bas on January 20, 2015, 09:29:42 AM

Title: Array types
Post by: bas on January 20, 2015, 09:29:42 AM
I recently read
http://www.drdobbs.com/architecture-and-design/cs-biggest-mistake/228701625
where the author states that the (one of) the biggest mistakes made in C was
converting an array to a pointer when calling a function, so (C-code)
Code: [Select]
int array[4];
int* ip = &array[0];
myfunction(array);
myfunction(ip);
the two calls are equal. One idea would be to make this distinction. One limit would be
that the array would be a known size (in function prototype), eg (C2 code)
Code: [Select]
func void setMacnr(char[4] macnr) { .. }
A function that would take a variable sized array (like string functions) would still require a pointer and a size
argument.

Title: Re: Array types
Post by: kyle on January 23, 2015, 10:00:49 PM
Thanks for the link.  Walter Bright makes a good case for this. 

Passing "fat pointers," as Walter mentions, is one way to solve this.   Go uses them to pass values and vtables. 

Not only are arrays and pointers conflated, but now you have "magic" happening in that arrays are treated as pass-by-reference whereas other values must have "*/&" to show that they are passed by reference.  I actually find this aspect of the automatic conversion to be more problematic.  If I pass something by value, I expect that there is nothing that will alter the values in the caller.  If I pass something by reference, I accept that the callee could modify data in the caller.

Pass by value:
Code: [Select]
int foo(int p);

int x;

foo(x);


Pass by reference:
Code: [Select]
int foo(int *p);

int x;

foo(&x);


Pass by value:
Code: [Select]
int foo(struct bar p);

struct bar x;

foo(x);

Pass by reference:
Code: [Select]
int foo(int p[]);

int x[2];

foo(x);

Huh?  This really violates the principle of least surprise.

If I pass a struct without explicitly getting its address, the struct is copied.  Arrays should be too.  Are there other things that are treated specially too?

I have programmed in C for so long that I never really thought too much about this.  Java does the same thing with primitive types vs. objects.

Good find!

Best,
Kyle

Title: Re: Array types
Post by: norm on February 14, 2015, 11:04:18 PM
I found this proposal by John Nagel on Lambda The Ultimate : http://lambda-the-ultimate.org/node/4573 (http://lambda-the-ultimate.org/node/4573)

The idea is to tie together parameters in a function declaration so the compiler can see that one of the parameters is the length of the array in the other parameter. Look at the "n" in this example he gives:

    int read(int fd, char (&buf)[n], size_t n); 

Even if this proposal isn't appropriate, maybe the reaction and discussion is informative.


Title: Re: Array types
Post by: kyle on February 18, 2015, 06:23:32 PM
Oooh!  Thanks for the link!

Interesting proposal. 

Title: Re: Array types
Post by: bas on March 11, 2015, 08:16:42 AM
I'm currently playing with the idea of forbidding passing array types like (int[] a) as function argument. A developer would have to use (int* a). In the function body he/she could do a[4].

Anyone have a any other ideas on this?
Title: Re: Array types
Post by: kyle on March 17, 2015, 10:24:12 PM
Well, it depends  :)

If you want to do things exactly the same way as C (conversion from array to pointer), then there isn't much you can do.   

However, if you are willing to extend things a bit, then you could pass array bounds in either fat pointers, or via metadata that can be retrieved via the pointer.

Personally, I would like to be able to pass

Code: [Select]
int a[14] = {0,};

foo(a);

and have
Code: [Select]
foo() be defined:

Code: [Select]
void foo(int an_array[])

And have the passed array get copied.  If I want to share it, I'll explicitly pass a pointer.

Of course, if you did that, then to call C libraries, you would need to make sure that you explicitly passed a pointer to the first element of the array.

I'll think about this more...  It isn't that clear.
Title: Re: Array types
Post by: bas on March 20, 2015, 09:29:08 AM
It would indeed be nice to let caller choose calling by value (thus copy) or by reference.
External C libraries would make this decision hard indeed. It seems simple but has
many consequences as you already stated...