Thursday, October 20, 2022

Digest for comp.lang.c++@googlegroups.com - 25 updates in 3 topics

Lynn McGuire <lynnmcguire5@gmail.com>: Oct 19 09:01PM -0500

I put the following cast into my code and one of my programmers wants me
to use static cast. Why ?
https://en.cppreference.com/w/cpp/language/static_cast
 
longint nfac [8];
fem::str <8> * nfac_str = (fem::str <8> *) nfac;
 
fem::str <8> is an 8 character object that acts like a Fortran
character*8. longint is a long long.
 
Thanks,
Lynn
"daniel...@gmail.com" <danielaparker@gmail.com>: Oct 19 07:40PM -0700

On Wednesday, October 19, 2022 at 10:01:35 PM UTC-4, Lynn McGuire wrote:
 
> I put the following cast into my code and one of my programmers wants me
> to use static cast.
 
I'm pretty sure static_cast would give an invalid type conversion error.
 
> fem::str <8> * nfac_str = (fem::str <8> *) nfac;
 
> fem::str <8> is an 8 character object that acts like a Fortran
> character*8. longint is a long long.
 
I think that's undefined behaviour.
 
Daniel
Andrey Tarasevich <andreytarasevich@hotmail.com>: Oct 19 08:09PM -0700

On 10/19/2022 7:01 PM, Lynn McGuire wrote:
>    fem::str <8> * nfac_str = (fem::str <8> *) nfac;
 
> fem::str <8> is an 8 character object that acts like a Fortran
> character*8.  longint is a long long.
 
`static_cast`? `static_cast` cannot do this. One of your programmers
probably meant `reinterpret_cast`. That would still be barely kosher
assuming the resultant type is actually an array of `[signed/unsigned]
char`.
 
In reality you need `std::bit_cast` here (C++20). Or the good old
`std::memcpy`.
 
--
Best regards,
Andrey.
Lynn McGuire <lynnmcguire5@gmail.com>: Oct 20 12:21AM -0500

>> character*8. longint is a long long.
 
> I think that's undefined behaviour.
 
> Daniel
 
Why ? They are both pointers to 8 byte objects. I am just declaring
that I want to use the same address as a 8 byte character string (no
null !) or a long long integer.
 
Thanks,
Lynn
Juha Nieminen <nospam@thanks.invalid>: Oct 20 05:44AM

> I put the following cast into my code and one of my programmers wants me
> to use static cast. Why ?
 
static_cast protects you from accidentally converting between incompatible
types. (If you don't intend to convert between incompatible types, yet that
still happens, it's most certainly a bug.)
 
If you intentionally do want to convert between incompatible types, it's
a good idea to use reinterpret_cast instead of a C style cast. That's
because it expresses intent better (it kind of self-documents the code
saying "yes, I intend to cast between incompatible types here, it's
not an oversight or error"). It also makes it easier to find such
casts in the code.
 
(Also, I believe reinterpret_cast is still more restrictive than a
C style cast. I think it doesn't allow you to remove constness, which
is also a good idea even when converting between incompatible types.
Accidentally removing constness can easily change a well-defined
behavior into undefined.)
 
> fem::str <8> * nfac_str = (fem::str <8> *) nfac;
 
> fem::str <8> is an 8 character object that acts like a Fortran
> character*8. longint is a long long.
 
Technically speaking that's UB, but I'm not aware of any modern system
it will cause problems. Well, at least if you use a proper 'alignas'
qualifier with that 'nfac'. (Since the type is long long, the alignas
might be superfluous, but it doesn't hurt.)
Andrey Tarasevich <andreytarasevich@hotmail.com>: Oct 19 11:21PM -0700

On 10/19/2022 10:21 PM, Lynn McGuire wrote:
 
> Why ?  They are both pointers to 8 byte objects.  I am just declaring
> that I want to use the same address as a 8 byte character string (no
> null !) or a long long integer.
 
You can't, neither in C nor in C++. An object (lvalue) of type `T` can
only be accessed as an object (lvalue) of type `T` (with few
exceptions). This is well known as the "strict aliasing" rule.
 
--
Best regards,
Andrey.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 20 08:52AM +0200

Am 20.10.2022 um 04:01 schrieb Lynn McGuire:
> character*8.  longint is a long long.
 
> Thanks,
> Lynn
 
I don't use static-cast at all. It provides some kind of child
proof lock in a a sense that you can less mistakes because you
can only convert to in a compatible type, but this never happened
to me before and normal C-style casts are readable better for me.
Juha Nieminen <nospam@thanks.invalid>: Oct 20 07:19AM


> You can't, neither in C nor in C++. An object (lvalue) of type `T` can
> only be accessed as an object (lvalue) of type `T` (with few
> exceptions). This is well known as the "strict aliasing" rule.
 
AFAIK any value of any type can always be safely read with an (unsigned)
char pointer (as long as you remain within the limits of the type size).
 
If if weren't, it would be impossible to eg. create your own version
of memcmp().
Andrey Tarasevich <andreytarasevich@hotmail.com>: Oct 20 12:21AM -0700

On 10/20/2022 12:19 AM, Juha Nieminen wrote:
> char pointer (as long as you remain within the limits of the type size).
 
> If if weren't, it would be impossible to eg. create your own version
> of memcmp().
 
That is one of the exceptions.
 
--
Best regards,
Andrey.
Paul N <gw7rib@aol.com>: Oct 20 04:23AM -0700

On Thursday, October 20, 2022 at 6:21:25 AM UTC+1, Lynn McGuire wrote:
> They are both pointers to 8 byte objects. I am just declaring
> that I want to use the same address as a 8 byte character string (no
> null !) or a long long integer.
 
Isn't that exactly what a union is for? Though if you are hoping to put in values of one type and read them out as values of the other then you would need to check that this is actually defined in your implementation.
Ben Bacarisse <ben.usenet@bsb.me.uk>: Oct 20 02:14PM +0100

>> that I want to use the same address as a 8 byte character string (no
>> null !) or a long long integer.
 
> Isn't that exactly what a union is for?
 
I'd say the main purpose is to save space by storing objects of
different types in the space required by the largest. This inevitably
raises the question accessing an object in a union that was no the last
object stored in a union -- so called type punning.
 
This is defined /in C/, though the result is obviously not defined by
the C standard which only says that the bytes are interpreted as an
object of the type used for access.
 
However it's undefined in C++.
 
--
Ben.
scott@slp53.sl.home (Scott Lurndal): Oct 20 01:55PM

> fem::str <8> * nfac_str = (fem::str <8> *) nfac;
 
>fem::str <8> is an 8 character object that acts like a Fortran
>character*8. longint is a long long.
 
Young C++ programmers don't understand C, so they think
that static_cast<fem::str<8>*> is more "readable". Heh.
Gawr Gura <gawrgura@mail.hololive.com>: Oct 20 02:50PM

>> I put the following cast into my code and one of my programmers wants
me
>> to use static cast. Why ?
 
> static_cast protects you from accidentally converting between
incompatible
> types. (If you don't intend to convert between incompatible types, yet
that
> saying "yes, I intend to cast between incompatible types here, it's
> not an oversight or error"). It also makes it easier to find such
> casts in the code.
 
This is the correct answer. The C-style cast is one cast to rule them all.
You can do things you don't intend to with it (e.g., cast away qualifiers)
and your compiler won't stop you. If you try to do the wrong thing with
static/dynamic/const/reinterpret casts you will get an error. Do what you
prefer but if you have to ask why one would use a static_cast then I think
the C++ casts are preferable.
JiiPee <kerrttuPoistaTama11@gmail.com>: Oct 20 05:52PM +0300

but boost::numberi_cast is something to consider, because it checks
more... it checks if the number is valid in the conversation.
 
On 20/10/2022 09:52, Bonita Montero wrote:
JiiPee <kerrttuPoistaTama11@gmail.com>: Oct 20 05:53PM +0300

Especially dynamic_cast can help alot, because we might make human
mistakes in polymorhism.
 
On 20/10/2022 17:50, Gawr Gura wrote:
casts in the code.
JiiPee <kerrttuPoistaTama11@gmail.com>: Oct 20 05:55PM +0300

On 20/10/2022 16:55, Scott Lurndal wrote:
> Young C++ programmers don't understand C, so they think
> that static_cast<fem::str<8>*> is more "readable". Heh.
 
its surely not more readable.
but dynamic_cast is surely useful checking class hierarkies.
scott@slp53.sl.home (Scott Lurndal): Oct 20 03:01PM

>> that static_cast<fem::str<8>*> is more "readable". Heh.
 
>its surely not more readable.
>but dynamic_cast is surely useful checking class hierarkies.
 
dynamic_cast provides some level of introspection, which can
be useful; albeit at a small cost (for the typeid metadata).
"daniel...@gmail.com" <danielaparker@gmail.com>: Oct 20 08:11AM -0700

On Thursday, October 20, 2022 at 1:21:25 AM UTC-4, Lynn McGuire wrote:
 
> Why ? They are both pointers to 8 byte objects. I am just declaring
> that I want to use the same address as a 8 byte character string (no
> null !) or a long long integer.
 
ubsan will complain about load of misaligned address. In these cases you
need to use memcpy instead of cast and assignment.
 
See https://stackoverflow.com/questions/47619944/load-of-misaligned-address-and-ubsan-finding
JiiPee <kerrttuPoistaTama11@gmail.com>: Oct 20 06:32PM +0300

On 20/10/2022 18:01, Scott Lurndal wrote:
> dynamic_cast provides some level of introspection, which can
> be useful; albeit at a small cost (for the typeid metadata).
 
sure, although about 99.9% in cases the speed is not an issue in these
object oriented programs. But sure, if speed is in essence, one should
consider not using it.
scott@slp53.sl.home (Scott Lurndal): Oct 20 04:07PM

>> be useful; albeit at a small cost (for the typeid metadata).
 
>sure, although about 99.9% in cases the speed is not an issue in these
>object oriented programs.
 
I would argue against this viewpoint, myself.
Andrey Tarasevich <andreytarasevich@hotmail.com>: Oct 20 09:17AM -0700

On 10/20/2022 4:23 AM, Paul N wrote:
>> that I want to use the same address as a 8 byte character string (no
>> null !) or a long long integer.
 
> Isn't that exactly what a union is for? Though if you are hoping to put in values of one type and read them out as values of the other then you would need to check that this is actually defined in your implementation.
 
"Exactly what a union is for"?
 
It is true that unions have been used for type punning from time to
time, but this is not "what a union is for". Union is a
memory-time-sharing feature that exists for reducing memory usage. You
don't normally "put in values of one type and read them out as values of
the other". That's not exactly what union is for.
 
--
Best regards,
Andrey.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 20 09:52AM -0700

> memory-time-sharing feature that exists for reducing memory usage. You
> don't normally "put in values of one type and read them out as values
> of the other". That's not exactly what union is for.
 
Agreed.
 
K&R1 (1978) introduces unions in section 6.8. It discusses holding
objects of different types at different times; it says nothing about
type punning. (The version of C discussed in the 1975 manual didn't
have unions.)
 
Of course programmers, being programmers, do not tend to restrict
themselves to the original intent of any feature.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
Muttley@dastardlyhq.com: Oct 20 04:16PM

On Wed, 19 Oct 2022 15:35:59 GMT
 
>In this case, the use of "Cromulent" was perfectly cromulent :-)
 
>The term originally was coined by a Simpsons writer, and has
>subsequently reached the Merriam-Webster dictionary.
 
Rather apt I suppose given Flibble does seem to impersonate Bart :)
Lynn McGuire <lynnmcguire5@gmail.com>: Oct 20 12:25AM -0500

On 10/17/2022 3:51 PM, Jens wrote:
> global function (not a member of a class).
> How can I do this ?
 
> Thanks for ideas.
 
You need to get a permanent pointer to that event handler so you can
register it. So, make it a static method.
 
Registering event handlers is tricky. You need to keep a vector of them
and remove them when no longer valid.
 
Lynn
JiiPee <kerrttuPoistaTama11@gmail.com>: Oct 20 06:36PM +0300

On 18/10/2022 12:27, Juha Nieminen wrote:
> I didn't ask for your life story.
 
:)
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: