Jump to page: 1 2 3
Thread overview
Disallow arrays as pointers
Oct 30, 2011
bearophile
Oct 30, 2011
Jonathan M Davis
Oct 30, 2011
bearophile
Oct 30, 2011
Jonathan M Davis
Oct 30, 2011
bearophile
Oct 30, 2011
Timon Gehr
Oct 31, 2011
bearophile
Oct 31, 2011
bearophile
Oct 31, 2011
Timon Gehr
Nov 02, 2011
deadalnix
Oct 31, 2011
deadalnix
Oct 30, 2011
Andrej Mitrovic
Oct 31, 2011
Don
Oct 31, 2011
bearophile
Oct 31, 2011
Timon Gehr
Nov 01, 2011
bearophile
Nov 01, 2011
Timon Gehr
Nov 02, 2011
bearophile
Nov 02, 2011
bearophile
Nov 02, 2011
deadalnix
Nov 03, 2011
Don
May 13, 2023
Salih Dincer
May 13, 2023
Salih Dincer
Nov 05, 2011
Dejan Lekic
Nov 06, 2011
Don
Nov 07, 2011
Dejan Lekic
Nov 09, 2011
Don
October 30, 2011
I have translated C code similar to:


something foo(int n) {
    int *array = malloc(n * sizeof(int));

    int i;
    for (...) {
        for (i = 0; i < n; i++, array++) {
            *array = ...;
            *array = ...;
        }
    ...
}


Into D2 code similar to:


something foo(int n) {
    auto array = new int[n];

    size_t index;
    foreach (...) {
        foreach (i; 0 .. n) {
            array[index] = ...;
            *array = ...;
            index++;
        }
    ...
}


Do you see the bug I have found during the debugging?

I think the D2 compiler has to catch this bug:

*array = ...;

D arrays aren't pointers. Letting the compiler see them as pointers is bug-prone, not tidy, and doesn't help D newbies understand how D represents its arrays.


My bug report: http://d.puremagic.com/issues/show_bug.cgi?id=3990


Some very good comments about this topic: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=135391

Bye,
bearophile
October 30, 2011
On Sunday, October 30, 2011 17:29:36 bearophile wrote:
> I have translated C code similar to:
> 
> 
> something foo(int n) {
>     int *array = malloc(n * sizeof(int));
> 
>     int i;
>     for (...) {
>         for (i = 0; i < n; i++, array++) {
>             *array = ...;
>             *array = ...;
>         }
>     ...
> }
> 
> 
> Into D2 code similar to:
> 
> 
> something foo(int n) {
>     auto array = new int[n];
> 
>     size_t index;
>     foreach (...) {
>         foreach (i; 0 .. n) {
>             array[index] = ...;
>             *array = ...;
>             index++;
>         }
>     ...
> }
> 
> 
> Do you see the bug I have found during the debugging?
> 
> I think the D2 compiler has to catch this bug:
> 
> *array = ...;
> 
> D arrays aren't pointers. Letting the compiler see them as pointers is bug-prone, not tidy, and doesn't help D newbies understand how D represents its arrays.
> 
> 
> My bug report: http://d.puremagic.com/issues/show_bug.cgi?id=3990
> 
> 
> Some very good comments about this topic: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&ar ticle_id=135391

Arrays in D implicitly convert to their ptr property, so they essentially _are_ pointers in that sense. Now, personally, I think that it would be a good idea for them _not_ to implicitly convert, forcing you to explicitly use the ptr property, since you really shouldn't be treating arrays as pointers in D code. It's primarily when interacting with C code that you need to do that sort of thing, and the ptr property deals with it just fine.

However, I don't think that you're going to find a general consensus that the implicit conversion is bad, and changing it now would likely break a lot of code. So, while I do think that it would be a good change, I really don't think that it's going to happen at this point.

- Jonathan M Davis
October 30, 2011
I didn't know that would compile.

Anyway, if one really wants to treat arrays like pointers he can do: *array.ptr
October 30, 2011
Jonathan M Davis:

> However, I don't think that you're going to find a general consensus that the implicit conversion is bad,

I'll keep count how many are against this idea.


> and changing it now would likely break a lot of code.

How much code is broken by this?
It's bad D code that's easy to fix adding a ".ptr", or using "-d" (deprecated) to compile the code.


 So, while I do think that it would be a good change, I really don't
> think that it's going to happen at this point.

Let's break some code, to avoid even more bugs/breakage later! :-)

(I am asking for some other little breaking changes in Bugzilla. This is not the only one.)

Bye,
bearophile
October 30, 2011
On Sunday, October 30, 2011 18:10:06 bearophile wrote:
> Jonathan M Davis:
> > However, I don't think that you're going to find a general consensus that the implicit conversion is bad,
> 
> I'll keep count how many are against this idea.
> 
> > and changing it now would likely break a lot of code.
> 
> How much code is broken by this?
> It's bad D code that's easy to fix adding a ".ptr", or using "-d"
> (deprecated) to compile the code.

I think that it will primarily affect strings (though in many such cases toStringz or toUTFz should generally be used), but from what I understand, it's quite common for D programmers interacting with C code to just pass arrays to C functions without using the ptr property.

- Jonathan M Davis
October 30, 2011
Jonathan M Davis:

> from what I understand, it's quite common for D programmers interacting with C code to just pass arrays to C functions without using the ptr property.

That code works with an implicit conversion that saves the typing of 4 more chars, while introducing something that is negative for both newbie D programmers and more trained ones. ".ptr" was introduced in D to avoid this.

In general I find it curious that D design tries to avoid some mistakes of the C design, and to disallow some bug-prone features of C, like some implicit type conversions. But then, it seems that D doesn't take a lot of care to avoid bug-prone "features" that it has introduced, that were not present in C (like the one discussed here, like lax management of strings that represent operators of operator overloading, etc.)

Thank you for your answers,
bye,
bearophile
October 30, 2011
On 10/31/2011 12:03 AM, bearophile wrote:
> Jonathan M Davis:
>
>> from what I understand,
>> it's quite common for D programmers interacting with C code to just pass
>> arrays to C functions without using the ptr property.
>
> That code works with an implicit conversion that saves the typing of 4 more chars, while introducing something that is negative for both newbie D programmers and more trained ones. ".ptr" was introduced in D to avoid this.
>
> In general I find it curious that D design tries to avoid some mistakes of the C design, and to disallow some bug-prone features of C, like some implicit type conversions.
> But then, it seems that D doesn't take a lot of care to avoid bug-prone "features" that it has introduced, that were not present in C (like the one discussed here, like lax management of strings that represent operators of operator overloading, etc.)
>

I have never had a bug because of arrays implicitly converting to pointers. I'd sometimes even like e.g. ++array to mean array=array[1..$]. A lot of C's carefully designed syntactic elegance is lost when going from pointers/iterators to arrays and ranges. But why is *array not bounds checked in non-release mode? I think it should be.

The lax management of strings is not a bug-prone feature. (in the sense that it would be likely to produce erroneous code because of subtle typing mistakes.) Sure, if the implementer of the aggregate using operator overloading does not handle invalid sequences, it can be "exploited" to gain access to private members and/or implementation details. That does not happen by accident.
I don't think Phobos helps enough to make correct handling easy, maybe some simple isOpBinary(string), isOpUnary(string), etc. templates would be worth adding.

October 31, 2011
Timon Gehr:

> I have never had a bug because of arrays implicitly converting to pointers.

Good.


> A lot of C's carefully designed syntactic elegance is lost when going from pointers/iterators to arrays and ranges.

You see that D design tries hard to avoid the need to use pointers as much as possible, because pointers are bug prone, give less readable code, and they are not needed in most cases (you use something a bit higher level, like arrays or references).
Some people say that C language is as elegant as a katana sword, but I have to say that most times you want to keep it in its sheath :-)


> But why is *array not bounds checked in non-release mode? I think it should be.

In D there are arrays, and there are pointers. Arrays are bound-checked, pointers aren't. So when you use arrays as pointers, or when you use somearray.ptr[x] you have lost array bounds. Adding a third intermediate type is not a good idea, it increases language and implementation complexity for a practice that is meant as discouraged since the introduction of the ptr field.

Bye,
bearophile
October 31, 2011
Timon Gehr:

> A lot of C's carefully designed syntactic elegance is lost when going from pointers/iterators to arrays and ranges.

I think that a large part of that C syntactic elegance is an illusion. From my experience, I want my code to look very simple to read and clean every time this is possible. I want it to be easy to port to other languages, because I have do it often enough. C code that uses lot of pointers is often bug-prone, messy and hard to safely translate to other languages.

There are situation where pointers are necessary or are better than the alternatives, or they give the needed flexibility, so I prefer a language with pointers, but in a well designed language those situations are not common, and I think raw pointers should be avoided when they are not needed. I have debugged enough C code to be rather sure of this. Good luck with your pointers.

Bye,
bearophile
October 31, 2011
On 30.10.2011 22:29, bearophile wrote:
> I have translated C code similar to:
>
>
> something foo(int n) {
>      int *array = malloc(n * sizeof(int));
>
>      int i;
>      for (...) {
>          for (i = 0; i<  n; i++, array++) {
>              *array = ...;
>              *array = ...;
>          }
>      ...
> }
>
>
> Into D2 code similar to:
>
>
> something foo(int n) {
>      auto array = new int[n];

>              *array = ...;

> I think the D2 compiler has to catch this bug:
>
> *array = ...;
>
> D arrays aren't pointers. Letting the compiler see them as pointers is bug-prone, not tidy, and doesn't help D newbies understand how D represents its arrays.

What's New for D 0.177
Dec 9, 2006
New/Changed Features
    Arrays no longer implicitly convert to pointers unless -d is used.

For example, this code:

void main()
{
   int[] x = new int[59];
   int *q = x;
}
compiled on 0.176 and earlier, but not any more. The case involving *arr seems to have just been missed. This is a simple accepts-invalid bug. Not an enhancement request.

« First   ‹ Prev
1 2 3