Author Topic: Array types  (Read 17317 times)

bas

  • Full Member
  • ***
  • Posts: 220
    • View Profile
Array types
« 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.


kyle

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Array types
« Reply #1 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


norm

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Array types
« Reply #2 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

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.



kyle

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Array types
« Reply #3 on: February 18, 2015, 06:23:32 PM »
Oooh!  Thanks for the link!

Interesting proposal. 


bas

  • Full Member
  • ***
  • Posts: 220
    • View Profile
Re: Array types
« Reply #4 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?

kyle

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Array types
« Reply #5 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.

bas

  • Full Member
  • ***
  • Posts: 220
    • View Profile
Re: Array types
« Reply #6 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...