Jump to page: 1 2
Thread overview
Comparing pointers in C and D
Feb 15, 2023
Olivier Pisano
Feb 16, 2023
Ali Çehreli
Feb 16, 2023
Paul Backus
Feb 16, 2023
Ali Çehreli
Feb 16, 2023
Paul Backus
Feb 16, 2023
Ali Çehreli
Feb 16, 2023
Olivier Pisano
Feb 16, 2023
Olivier Pisano
Feb 16, 2023
Timon Gehr
Feb 16, 2023
Dukc
February 15, 2023

Hello,

Today a colleague of mine gave me a link to this article about comparing pointers in C :

https://pvs-studio.com/en/blog/posts/cpp/0576/

Playing with the first code example in Compiler explorer, it seems that the pointer comparison is always false in GCC once optimizations are enabled, while it is always true with Clang, no matter the optimization level.

What bothers me is that the same behavior can be observed respectively with GDC (false) and LDC (true), at least with the versions available in compiler explorer.

Does the D spec define pointer comparison semantics ? What should the correct behaviour be? I can understand the C standard wording in regards to segmented memory archs, but I must admit I have trouble justifying it on a PC with linear address space...

Best regards.

February 15, 2023
On 2/15/23 12:07, Olivier Pisano wrote:

> https://pvs-studio.com/en/blog/posts/cpp/0576/

I haven't read the article but the example has the following:

    int a, b;
    int *p = &a;
    int *q = &b + 1;

As far as I know, that pointer arithmetic applied to a single object is undefined behavior.

(I would love to learn otherwise if I am mistaken there. But I've just checked again, an expression like '&b + 1' can only be applied to pointers into array elements. Since b is not an array element, I am confident that it's undefined behavior.)

If so, I think both gcc and llvm are aware of undefined behavior and it looks trivial to catch the one above. If they detect undefined behavior, they can produce any result. But I don't know whether they apply that logic. (?)

Ali

February 16, 2023
On 16/02/2023 2:13 PM, Ali Çehreli wrote:
>      int a, b;
>      int *p = &a;
>      int *q = &b + 1;
> 
> As far as I know, that pointer arithmetic applied to a single object is undefined behavior.

@safe will of course prevent this.

So as far as D is concerned its a solved problem ;)
February 16, 2023
On Thursday, 16 February 2023 at 01:13:17 UTC, Ali Çehreli wrote:
> On 2/15/23 12:07, Olivier Pisano wrote:
>
> > https://pvs-studio.com/en/blog/posts/cpp/0576/
>
> I haven't read the article but the example has the following:
>
>     int a, b;
>     int *p = &a;
>     int *q = &b + 1;
>
> As far as I know, that pointer arithmetic applied to a single object is undefined behavior.

In C the addition itself is defined behavior (you are allowed to create a pointer to "one past the end" of an object), but dereferencing it would be UB. [1] The D spec does not say anything about this, but I think it's safe to assume that it inherits C's semantics.

[1] http://port70.net/~nsz/c/c11/n1570.html#6.5.6p8
February 16, 2023
If I change the variable types by arrays of 1 int, I get the same result :

https://godbolt.org/z/YWTvTPr4W

You are right, it is certainly a UB, but it seems that the GCC optimizer treats scalars and arrays the same way, as soon as it can statically deduce the arithmetic goes past the end of the object memory space.


February 16, 2023
On Thursday, 16 February 2023 at 06:37:54 UTC, Olivier Pisano wrote:
> If I change the variable types by arrays of 1 int, I get the same result :
>
> https://godbolt.org/z/YWTvTPr4W
>
> You are right, it is certainly a UB, but it seems that the GCC optimizer treats scalars and arrays the same way, as soon as it can statically deduce the arithmetic goes past the end of the object memory space.

And now I start wondering how can STL algorithms even work since the end iterator is past the last element. Gosh...
February 15, 2023
On 2/15/23 22:28, Paul Backus wrote:

> In C the addition itself is defined behavior (you are allowed to create
> a pointer to "one past the end" of an object)

To be pedantic, "one past" is always applied to "the last element of the array object". My reaction was to the non-array object in the code. :)

> it's safe to assume that it inherits C's semantics.

I think so too.

Ali

February 15, 2023
On 2/15/23 22:56, Paul Backus wrote:

> "For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type."
> 
> http://port70.net/~nsz/c/c11/n1570.html#6.5.6p7

That's helpful. Thanks! :)

Ali

February 16, 2023
On Thursday, 16 February 2023 at 06:46:16 UTC, Ali Çehreli wrote:
> On 2/15/23 22:28, Paul Backus wrote:
>
> > In C the addition itself is defined behavior (you are allowed
> to create
> > a pointer to "one past the end" of an object)
>
> To be pedantic, "one past" is always applied to "the last element of the array object". My reaction was to the non-array object in the code. :)

"For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type."

http://port70.net/~nsz/c/c11/n1570.html#6.5.6p7
February 16, 2023

On Wednesday, 15 February 2023 at 20:07:35 UTC, Olivier Pisano wrote:

>

Does the D spec define pointer comparison semantics ? What should the correct behaviour be? I can understand the C standard wording in regards to segmented memory archs, but I must admit I have trouble justifying it on a PC with linear address space...

I cannot find a relevant line in the spec. It should be defined behaviour, as it is allowed in @safe, but the result of the comparison is probably undefined, in the same way a bool variable initialised with = void is undefined.

« First   ‹ Prev
1 2