C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Make all data pointers intercompatible

From: Thiago Macieira <thiago_at_[hidden]>
Date: Sun, 12 May 2024 16:41:58 -0700
On Sunday 12 May 2024 15:45:03 GMT-7 Frederick Virchanza Gotham via Std-
Proposals wrote:
> On Thu, May 9, 2024 at 4:50 PM Thiago Macieira wrote:
> > Right.
> >
> > What's the problem?
>
> The problem is that C++ programmers today in 2024 are hindered by an
> old compiler that's rumoured to have existed (which I'm beginning to
> doubt ever existed at all). I don't want to hear people throwing
> around words like 'exotic' -- I need a vendor name, product name and
> year of release for a C++ (or even C) compiler whose char* is bigger
> than its double*. Can anyone actually name a single compiler that has
> sizeof(char*) > sizeof(double*)? I can't find anything from searching
> the web, and ChatGPT just told me now that it doesn't know of any
> either. If I ask ChatGPT to tell me about a compiler that has data
> pointers a different size to code pointers, it comes back with "The
> Keil C51 compiler for the Intel 8051 microcontroller" -- but it can't
> give me an example of a C/C++ compiler whose char* is different in
> size to any other data pointer.

Sorry, maybe I should rephrase: what would making it definite that all data
pointers have the same size accomplish? Where would it help? What problems
does it solve that can't be solved now?

> So C++26 should mandate that the following code is well-formed with
> well-defined behaviour:
>
> #include <iostream> // cout, endl
>
> double long *Backwards(double long *const arg)
> {
> return (double long*)((char*)arg - 1);
> }
>
> double long *Forwards(double long *const arg)
> {
> return (double long*)((char*)arg + 1);
> }
>
> int main(void)
> {
> double long d = 123.456L;
> *Backwards(Forwards(&d)) = 666.0L;
> std::cout << d << std::endl;
> }

This is plain pointer conversion. I think it should be allowed. I don't know
what rules it would violate if it isn't.

But it's also orthogonal to the discussion: the size of a pointer
representation does not impede or help the above code.

> C++26 should mandate that all data pointers are the same size with the
> same representation, and it should explicitly say that it's safe to
> store the address of an unaligned T inside a T*. The following should
> also be OK:

No, that's different. It does not need to allow unaligned access at all,
therefore it does not need to allow storing of an unaligned address in a
pointer. That's independent of the size of the pointer.

> int main(void)
> {
> char c = 'a';
> *(char*)(double long*)(std::string*)(int*)&c = 'b'; // no
> problems here
> }

Indeed and there should be. I don't see any reason why the above should be
required to be allowed.

> And the Standard should also mandate that aliasing rules no longer
> apply once you cast a pointer. Consider the following function:
>
> void Func(double *const a, int const *const b)
> {
> *a += *(double*)b;
> *a += *(double*)b;
> }
>
> A compiler should be forbidden from optimising the above to:
>
> *a += *(double*)b * 2.0;
>
> because the cast from "int*" to "double*" turns off the aliasing
> rules, and so the compiler must accommodate the possibility that 'a'
> and 'b' point to the same double.

That's a subject I have little expertise on so will refrain from commenting.

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Principal Engineer - Intel DCAI Cloud Engineering

Received on 2024-05-12 23:42:05