- why use static_cast ? - 22 Updates
- CHAR_BIT is not eight - 1 Update
- calling a Event Handler within a class - 2 Updates
| 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:
Post a Comment