Hacker News new | past | comments | ask | show | jobs | submit login

I wrote about a simple addition to C that could eliminate most buffer overflows:

https://www.digitalmars.com/articles/C-biggest-mistake.html

I.e. offering a way that arrays won't automatically decay to pointers when passed as a function parameter.




Arrays are pointers. If they aren't pointers then you need to copy the data when you are giving an array as a function parameter. that's a lot slower. Being able to prepare an set of data in an array and then giving a pointer to a function is very useful. You could add a second type of array on top of what you have in C that includes more stuff, but if that's what you want you can implement that yourself with a struct.


An array is not a pointer. These are completely different data types. For example, you can't apply pointer arithmetic to arrays without casting them to pointers.


That's right. They are converted to pointers when passed to a function, even if the function declares the parameter as an array.


They're not converted but can be implicitly casted to pointer types.


No, they're converted. There is no such thing as an "implicit cast". And it's not specific to arguments in function calls.

Array types and pointer types are distinct.

An expression of array type is, in most but not all contexts, implicitly converted (really more of a compile-time adjustment) to an expression of pointer type that yields the address of the 0th element of the array object. The exceptions are when the array expression is the operand of a unary & (address-of) or sizeof operator, or when it's a string literal in an initializer used to initialize an array (sub)object. (The N1570 draft incorrectly lists _Alignof as another exception. In fact, _Alignof can only take a parenthesized type name as its operand.)

If you do:

    int arr[10];
    some_func(arr);
then arr is "converted" to the equivalent of &arr[0] -- not because it's an argument in a function call, but because it's not in one of the three contexts listed above in which the conversion doesn't take place.

Another rule that causes confusion here is that if you define a function parameter with an array type, it's treated as a pointer parameter. For example, these declarations are exactly equivalent:

    void func(int arr[]);
    void func(int arr[42]); // the 42 is quietly ignored
    void func(int *arr);
Suggested reading: http://www.c-faq.com/, particularly section 6, "Arrays and Pointers".

A conversion converts a value of one type to another type (possibly the same one). The term "cast" refers only to an explicit conversion, one specified by a cast operator (a parenthesized type name preceding the expression to be converted, like "(double)42"). An implicit conversion is one that isn't specified by a cast operator.


A little-known but useful C feature is static array indices, as in:

  void foo(int array[static 42]);
which means you can't pass in an array of less than 42 elements (and the compiler can warn you if it notices you are).


Sure you can. int aFoo[]; has many legal array operations possible:

  *(aFoo+3) should work fine and return the 4th int in the array.


I think your star operator there is making the compiler cast your array to pointer implicitly.


Its all symbols, so you can say whatever. But if it looks like a pointer, walks like a pointer, and quacks like a pointer, Its A Pointer.


they are accessed using pointer arithmetic, if you wanted them to contain length data, you would need a different access pattern. I think one of the great features of C is that it doesn't do anything under the hood, its all explicit. If you want to bounds check, then do it.


> they are accessed using pointer arithmetic

Not always. Consider:

    int a[3];
    a[1] = 2;
This is not using pointer arithmetic. Dump the generated code if you don't believe me :-)


Its still pointer arithmetic, its just done compile time rather then at execution. Still, you deserve style points :-)


Tell that to

  mov DWORD PTR [rsp - 8], 2


C currently replaces my use of an array with a pointer. This sucks, because I'd have taken the address if I wanted that.

Your proposal replaces my use of an array with two things, a pointer (as before) and a length. This is not too helpful, because I already could have done that if I'd wanted to.

What is missing is the ability to pass an array. Sometimes I want to toss a few megabytes on the stack. Don't stop me. I should be able to do that. The called function then has a copy of the original array that it can modify without mangling the original array in the caller.


> Your proposal replaces my use of an array with two things, a pointer (as before) and a length. This is not too helpful, because I already could have done that if I'd wanted to.

C doesn't have a reasonable way of doing that. I know my proposal works, because we've been using it in D for 20 years.


Your proposal does not work, at least when making the declarations binary compatible with older code.

Note that C is a pass-by-value language, so passing an array means that the called function can modify the content without the modifications being seen in the caller.

To sort of pass arrays in an ABI-compatible way, the version for older code would require putting the array inside a struct.

Even that doesn't fully work with any ABI that I've ever heard of. The struct doesn't really get passed. Disassemble the code if you have doubts. The caller allocates space for the struct, copies the struct there, and then passes a pointer to the struct. From the high-level view of the language, this is passing the struct, but the low level details are actually wrong.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: