Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

Successful and fortunate crime is called virtue. -- Seneca


devel / comp.lang.c / C pointer conversions, mismatches and void *

SubjectAuthor
* C pointer conversions, mismatches and void *James Harris
+* Re: C pointer conversions, mismatches and void *Andy Burns
|`- Re: C pointer conversions, mismatches and void *David Brown
+* Re: C pointer conversions, mismatches and void *Bart
|`* Re: C pointer conversions, mismatches and void *James Harris
| `* Re: C pointer conversions, mismatches and void *James Harris
|  `- Re: C pointer conversions, mismatches and void *James Kuyper
+- Re: C pointer conversions, mismatches and void *Öö Tiib
+- Re: C pointer conversions, mismatches and void *David Brown
`- Re: C pointer conversions, mismatches and void *James Kuyper

1
C pointer conversions, mismatches and void *

<s9iion$ki0$2@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16855&group=comp.lang.c++#16855

  copy link   Newsgroups: comp.lang.c
 by: James Harris - Sun, 6 Jun 2021 13:32 UTC

I understand that C allows one type of pointer to be converted to
another but what happens when there is no valid conversion for a
particular value of a pointer?

There are many potential ways to illustrate what I mean but to take a
simple example, if ip points to an int and cp points to a char (where a
char occupies fewer storage cells than an int) then in

ip = (int *) cp;

what happens if the particular value of cp is not correctly aligned for
an int? Options:

* The language (and thus the compiler) prohibits the conversion.
* A run-time exception occurs at the conversion statement.
* A run-time exception occurs when the int pointer is dereferenced.
* A run-time exception occurs on the dereference but only on some
architectures; on others an unaligned access takes place.
* The result is implementation defined.
* The effect is undefined.

Further, in C is any actual conversion of values carried out by a cast
or does the cast do no more than tell the compiler "I know what I am
doing; accept this value as valid".

I guess that, as far as the C language is concerned, pointers to
different types don't even need to be the same size so 'no conversion'
would, in general, be infeasible.

But then if a cast tells the compiler to effect an actual conversion
what would happen if the conversion goes via an intermediate stage of a
void pointer? Two scenarios: a void * variable and a void * cast.

Scenario 1: declare a void * variable as in

void * vp;

then 'convert' by storing one type in and retrieving another type from
that variable as in

vp = cp;
ip = vp;

If there's an actual conversion in the initial assignment at the top of
this post will the same conversion be applied in the case of going via
the void pointer? I guess it cannot be.

Scenario 2: change this post's initial assignment cast from int* to
void* as in

ip = (void *) cp;

If, again, int pointers and char pointers have different representations
would the void * tell the compiler not to carry out any conversion?

--
James Harris

Re: C pointer conversions, mismatches and void *

<ii4327FmmfnU3@mid.individual.net>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16858&group=comp.lang.c++#16858

  copy link   Newsgroups: comp.lang.c
 by: Andy Burns - Sun, 6 Jun 2021 14:05 UTC

James Harris wrote:

> I understand that C allows one type of pointer to be converted to
> another but what happens when there is no valid conversion for a
> particular value of a pointer?

On architectures I've used which actually *care* about byte/word/quad
address alignment, you get a SEGFAULT at runtime.

Re: C pointer conversions, mismatches and void *

<QR4vI.916200$zV01.571724@fx49.ams4>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16859&group=comp.lang.c++#16859

  copy link   Newsgroups: comp.lang.c
 by: Bart - Sun, 6 Jun 2021 14:21 UTC

On 06/06/2021 14:32, James Harris wrote:
> I understand that C allows one type of pointer to be converted to
> another but what happens when there is no valid conversion for a
> particular value of a pointer?
>
> There are many potential ways to illustrate what I mean but to take a
> simple example, if ip points to an int and cp points to a char (where a
> char occupies fewer storage cells than an int) then in
>
>  ip = (int *) cp;
>
> what happens if the particular value of cp is not correctly aligned for
> an int? Options:
>
> * The language (and thus the compiler) prohibits the conversion.
> * A run-time exception occurs at the conversion statement.
> * A run-time exception occurs when the int pointer is dereferenced.
> * A run-time exception occurs on the dereference but only on some
> architectures; on others an unaligned access takes place.
> * The result is implementation defined.
> * The effect is undefined.
>

I think this is all moot.

As well as allowing casts from T* to U* via void*, C also allows them
via intptr_t, or any int of a suitable size, or even one that is narrower.

In effect a pointer can contain garbage:

* Containing a misaligned address for the pointer type

* Pointing to non-existent or out of bounds memory.

* Containing a value that might not even be a considered a valid memory
address.

* Or it can point to valid, allocated memory, and inside a valid object.
It just happens to be the wrong one.

But this is C, what do you expect? In this kind of language you need the
flexibility.

If you don't, then use something like Rust. Then you have a more
elaborate and much more restrictive language.

Or one like Python where there are no pointers at all, in the language.
They all happen inside the implementation, which is likely in C. So such
a model can still work!

As to what happens when dereferencing any of those pointer values, you
might get a crash if you're lucky.

Re: C pointer conversions, mismatches and void *

<ea546231-15ef-4bb9-b338-9c21bd309e41n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16860&group=comp.lang.c++#16860

  copy link   Newsgroups: comp.lang.c
 by: Öö Tiib - Sun, 6 Jun 2021 14:32 UTC

On Sunday, 6 June 2021 at 16:32:18 UTC+3, James Harris wrote:
> I understand that C allows one type of pointer to be converted to
> another but what happens when there is no valid conversion for a
> particular value of a pointer?
>
> There are many potential ways to illustrate what I mean but to take a
> simple example, if ip points to an int and cp points to a char (where a
> char occupies fewer storage cells than an int) then in
>
> ip = (int *) cp;
>
> what happens if the particular value of cp is not correctly aligned for
> an int? Options:
>
> * The language (and thus the compiler) prohibits the conversion.
> * A run-time exception occurs at the conversion statement.

That does not happen, but the value of pointer ip may be some trap
representation on certain platforms as result.

> * A run-time exception occurs when the int pointer is dereferenced.
> * A run-time exception occurs on the dereference but only on some
> architectures; on others an unaligned access takes place.

Not exception. C does not have exceptions and platforms that have
(like Windows has SEH exceptions) do not AFAIK throw on such case.
There may happen trap because of unaligned access on certain
platforms and it may abort on others when instrumented with
debugging tools like UBSan configured to check alignment of
accesses.

> * The result is implementation defined.

Unlikely. Instead implementation authors strongly suggest against
doing it in their blogs.
> * The effect is undefined.

That is most common ... plus it often seems to work until it
screws something up around the memory where cp points to.

Re: C pointer conversions, mismatches and void *

<s9iq68$6l7$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16866&group=comp.lang.c++#16866

  copy link   Newsgroups: comp.lang.c
 by: James Harris - Sun, 6 Jun 2021 15:38 UTC

On 06/06/2021 15:21, Bart wrote:
> On 06/06/2021 14:32, James Harris wrote:

>> I understand that C allows one type of pointer to be converted to
>> another but what happens when there is no valid conversion for a
>> particular value of a pointer?
>>
>> There are many potential ways to illustrate what I mean but to take a
>> simple example, if ip points to an int and cp points to a char (where
>> a char occupies fewer storage cells than an int) then in
>>
>>   ip = (int *) cp;
>>
>> what happens if the particular value of cp is not correctly aligned
>> for an int? Options:
>>
>> * The language (and thus the compiler) prohibits the conversion.
>> * A run-time exception occurs at the conversion statement.
>> * A run-time exception occurs when the int pointer is dereferenced.
>> * A run-time exception occurs on the dereference but only on some
>> architectures; on others an unaligned access takes place.
>> * The result is implementation defined.
>> * The effect is undefined.
>>
>
> I think this is all moot.
>
> As well as allowing casts from T* to U* via void*, C also allows them
> via intptr_t, or any int of a suitable size, or even one that is narrower.

But conversion to and from intptr_t or any other pointer type would
effect two conversions, wouldn't it?

AIUI conversion to and from void* would always be implemented as
conversionless copies which /assume/ that no changes are required, void*
being large enough to hold a pointer to any data type.

That, of course, means that one is expected to store the same type of
pointer in a void* as one later reads from it.

--
James Harris

Re: C pointer conversions, mismatches and void *

<s9iqr0$9q8$2@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16868&group=comp.lang.c++#16868

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Sun, 6 Jun 2021 15:49 UTC

On 06/06/2021 16:05, Andy Burns wrote:
> James Harris wrote:
>
>> I understand that C allows one type of pointer to be converted to
>> another but what happens when there is no valid conversion for a
>> particular value of a pointer?
>
> On architectures I've used which actually *care* about byte/word/quad
> address alignment, you get a SEGFAULT at runtime.

Usually that would be when you dereference the pointer, rather than when
you do the conversion.

Re: C pointer conversions, mismatches and void *

<s9ir2g$d3s$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16869&group=comp.lang.c++#16869

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Sun, 6 Jun 2021 15:53 UTC

On 06/06/2021 15:32, James Harris wrote:
> I understand that C allows one type of pointer to be converted to
> another but what happens when there is no valid conversion for a
> particular value of a pointer?
>
> There are many potential ways to illustrate what I mean but to take a
> simple example, if ip points to an int and cp points to a char (where a
> char occupies fewer storage cells than an int) then in
>
>   ip = (int *) cp;
>
> what happens if the particular value of cp is not correctly aligned for
> an int? Options:
>
> * The language (and thus the compiler) prohibits the conversion.
> * A run-time exception occurs at the conversion statement.
> * A run-time exception occurs when the int pointer is dereferenced.
> * A run-time exception occurs on the dereference but only on some
> architectures; on others an unaligned access takes place.
> * The result is implementation defined.
> * The effect is undefined.
>

By the standards, the effect is undefined. That leaves compilers the
leeway to give implementation-defined behaviour if they want to.

The language could not prohibit the conversion of unaligned pointers
while still allowing the conversion of aligned pointers. The best it
can do is insist that you put in a cast - as you say, the cast means "I
know what I am doing".

>
> Further, in C is any actual conversion of values carried out by a cast
> or does the cast do no more than tell the compiler "I know what I am
> doing; accept this value as valid".

Some conversions may result in operation, such as conversion to _Bool,
or conversions between floating point types and integer types. Pointer
conversions usually do not, except perhaps on somewhat obscure platforms.

>
> I guess that, as far as the C language is concerned, pointers to
> different types don't even need to be the same size so 'no conversion'
> would, in general, be infeasible.
>
> But then if a cast tells the compiler to effect an actual conversion
> what would happen if the conversion goes via an intermediate stage of a
> void pointer? Two scenarios: a void * variable and a void * cast.
>
>
>
> Scenario 1: declare a void * variable as in
>
>   void * vp;
>
> then 'convert' by storing one type in and retrieving another type from
> that variable as in
>
>   vp = cp;
>   ip = vp;
>
> If there's an actual conversion in the initial assignment at the top of
> this post will the same conversion be applied in the case of going via
> the void pointer? I guess it cannot be.
>
>
>
> Scenario 2: change this post's initial assignment cast from int* to
> void* as in
>
>   ip = (void *) cp;
>
> If, again, int pointers and char pointers have different representations
> would the void * tell the compiler not to carry out any conversion?
>
>
>

Re: C pointer conversions, mismatches and void *

<s9j2u1$4tf$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16871&group=comp.lang.c++#16871

  copy link   Newsgroups: comp.lang.c
 by: James Kuyper - Sun, 6 Jun 2021 18:08 UTC

On 6/6/21 9:32 AM, James Harris wrote:
> I understand that C allows one type of pointer to be converted to
> another but what happens when there is no valid conversion for a
> particular value of a pointer?
>
> There are many potential ways to illustrate what I mean but to take a
> simple example, if ip points to an int and cp points to a char (where a
> char occupies fewer storage cells than an int) then in
>
> ip = (int *) cp;
>
> what happens if the particular value of cp is not correctly aligned for
> an int? Options:

"A pointer to an object type may be converted to a pointer to a
different object type. If the resulting pointer is not correctly aligned
68) for the referenced type, the behavior is undefined." (6.3.2.3p7).

> Further, in C is any actual conversion of values carried out by a cast
> or does the cast do no more than tell the compiler "I know what I am
> doing; accept this value as valid"?
"A pointer to void shall have the same representation and alignment
requirements as a pointer to a character type. 48) Similarly, pointers
to qualified or unqualified versions of compatible types shall have the
same representation and alignment requirements. All pointers to
structure types shall have the same representation and alignment
requirements as each other. All pointers to union types shall have the
same representation and alignment requirements as each other. Pointers
to other types need not have the same representation or alignment
requirements." (6.2.5p28).

Pay close attention to that last sentence. When pointers to two
different types have different representations, conversion from one to
the other is necessarily more than just a NoP.

As a practical matter, the only systems I've ever heard of which used
more than one pointer representation were systems for which, if T was a
type with an alignment requirement that is an integer multiple of the
word size, then T* was implemented using a small type that could point
only at words. For all other types, T* was implemented as a word pointer
plus a byte offset, which made those such pointers at least one byte
larger than the word-pointers. Conversion of a word pointer to a general
pointer resulted in a offset of 0. Conversion of a general pointer to a
word pointer would result in the offset being discarded.

I think you intended to restrict that question to pointer conversions,
but you didn't explicitly say so. If you actually intended to cover
arithmetic conversions as well, there's lots of cases where conversion
from one arithmetic type to another is non-trivial.

> But then if a cast tells the compiler to effect an actual conversion
> what would happen if the conversion goes via an intermediate stage of a
> void pointer? Two scenarios: a void * variable and a void * cast.
>
>
>
> Scenario 1: declare a void * variable as in
>
> void * vp;
>
> then 'convert' by storing one type in and retrieving another type from
> that variable as in
>
> vp = cp;
> ip = vp;
>
> If there's an actual conversion in the initial assignment at the top of
> this post will the same conversion be applied in the case of going via
> the void pointer? I guess it cannot be.
>
>
>
> Scenario 2: change this post's initial assignment cast from int* to
> void* as in
>
> ip = (void *) cp;
>
> If, again, int pointers and char pointers have different representations
> would the void * tell the compiler not to carry out any conversion?

6.3.2.3p7, which I quoted above, if a pointer not correctly aligned for
the type specfied by the cast, the behavior is undefined; how it was
created is irrelevant. Note, in particular, that it doesn't matter
whether the conversion was the result of a cast, or occurred implicitly.

Re: C pointer conversions, mismatches and void *

<s9lk70$o0p$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16893&group=comp.lang.c++#16893

  copy link   Newsgroups: comp.lang.c
 by: James Harris - Mon, 7 Jun 2021 17:15 UTC

On 06/06/2021 16:38, James Harris wrote:
> On 06/06/2021 15:21, Bart wrote:

....

>> As well as allowing casts from T* to U* via void*, C also allows them
>> via intptr_t, or any int of a suitable size, or even one that is
>> narrower.
>
> But conversion to and from intptr_t or any other pointer type would
> effect two conversions, wouldn't it?
>
> AIUI conversion to and from void* would always be implemented as
> conversionless copies which /assume/ that no changes are required, void*
> being large enough to hold a pointer to any data type.

I now think that's wrong. Per info about the standard from James Kuyper
"A pointer to void shall have the same representation and alignment
requirements as a pointer to a character type." So there would be two
conversions: to what is effectively a pointer to character type and from
such a pointer.

>
> That, of course, means that one is expected to store the same type of
> pointer in a void* as one later reads from it.

That's still true but it seems there would be the above two conversions.

--
James Harris

Re: C pointer conversions, mismatches and void *

<s9lugh$au$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16904&group=comp.lang.c++#16904

  copy link   Newsgroups: comp.lang.c
 by: James Kuyper - Mon, 7 Jun 2021 20:10 UTC

On 6/7/21 1:15 PM, James Harris wrote:
> On 06/06/2021 16:38, James Harris wrote:
>> On 06/06/2021 15:21, Bart wrote:
>
> ...
>
>>> As well as allowing casts from T* to U* via void*, C also allows them
>>> via intptr_t, or any int of a suitable size, or even one that is
>>> narrower.
>>
>> But conversion to and from intptr_t or any other pointer type would
>> effect two conversions, wouldn't it?
>>
>> AIUI conversion to and from void* would always be implemented as
>> conversionless copies which /assume/ that no changes are required, void*
>> being large enough to hold a pointer to any data type.
>
> I now think that's wrong. Per info about the standard from James Kuyper
> "A pointer to void shall have the same representation and alignment
> requirements as a pointer to a character type." So there would be two
> conversions: to what is effectively a pointer to character type and from
> such a pointer.

Precisely because they're required to have the same representation and
alignment requirements, conversions between void* and [[un]signed] char*
are NOPs. It's conversion to a pointer of any other type that might be
non-trivial.

>> That, of course, means that one is expected to store the same type of
>> pointer in a void* as one later reads from it.
>
> That's still true but it seems there would be the above two conversions.

The C standard describes it as a single direct conversion, without any
mention of any intermediate pointer type: "A pointer to void may be
converted to or from a pointer to any object type. A pointer to
any object type may be converted to a pointer to void and back again;
...." (6.3.2.3p1).

1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor