- Define object in header file - 3 Updates
- creating a new local variable after a goto - 12 Updates
- CHAR_BIT is not eight - 7 Updates
- Type conversion for hundreds of lines - 3 Updates
| Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Oct 14 08:50AM -0700 Usually we put all the declarations of objects in a header file, and all the definitions of objects in a source file. At the moment though I'm writing a 'universal header file' and so I want to put everything in the header file. There will be no accompanying source file. With the latest versions of the C++ Standard, we can use the 'inline' keyword to define a variable inside a header file, however I need to write my header file to compile with a C++03 compiler. So I resort to the following in the header file: SomeType &GetObj(void) { SomeType obj; return obj; } This works fine -- however there is a problem with the Texas Instruments compiler. The manual says that where you have a static variable inside an inline function, there are multiple copies of the static variable (one for each translation unit). So now I'm trying to devise a way of making this work for the Texas Instruments compiler too, maybe something like the following: SomeType &GetObj(void) { __asm("ABC: .bss mybuf, 64); return *static_cast<SomeType*>(static_cast<void*>(buf)); } I still haven't got this working yet. Anyone got any ideas? |
| David Brown <david.brown@hesbynett.no>: Oct 14 07:43PM +0200 On 14/10/2022 17:50, Frederick Virchanza Gotham wrote: > return obj; > } > This works fine -- however there is a problem with the Texas Instruments compiler. The manual says that where you have a static variable inside an inline function, there are multiple copies of the static variable (one for each translation unit). Are you sure? In C, that is the case (you are only allowed non-const static local variables in static inline functions in C). But not in C++. However, as I have mentioned before, TI sometimes considers the language standards as more of a set of guidelines than rules you can rely upon. > return *static_cast<SomeType*>(static_cast<void*>(buf)); > } > I still haven't got this working yet. Anyone got any ideas? Check that the TI compiler is really that bad for C++. Don't mess with inline assembly like this - it will lead to madness. The assembly details are different for each target, the linking is going to add complications, and TI's tools might not clear the .bss segment anyway. Try: enum objIdentifiers { obj1, obj2, objX, }; template <objIdentifiers i, class T> T& getObj() { static T obj; return obj; } Then you use it by calling : getObj<obj1, SomeType>(); Linking should merge all the static objects for the same template function. Use sensible names in the enumeration, of course. And override the template function for specific instances if you need non-default construction of the object. You can also add: static SomeType& this_object = getObj<objX, SomeType>; and refer simply to "this_object". I haven't tried any of this in real code, and with TI's tools you must always be sceptical until you have convinced yourself it works in practice. But the principle is correct - static locals in template functions are merged across the program link when the template parameters are the same, and separate when the template parameters do not match. The C++17 "inline variable" was added just to make this neater and simpler. |
| Andrey Tarasevich <andreytarasevich@hotmail.com>: Oct 14 11:03AM -0700 On 10/14/2022 8:50 AM, Frederick Virchanza Gotham wrote: > return obj; > } > This works fine -- however there is a problem with the Texas Instruments compiler. The manual says that where you have a static variable inside an inline function, there are multiple copies of the static variable (one for each translation unit). Um... I see neither `inline` nor `static` in the above code. Anyway, another way to emulate inline variables in earlier versions of C++ would be to implement it as a static member of a dummy template class template <typename DUMMY = void> struct InlinesImpl { static int a; // Declaration }; template <typename DUMMY> int InlinesImpl<DUMMY>::a = 42; // Definition typedef InlinesImpl<> Inlines; // Just for convenience // ... and now we can use `Inlines::a` as a global inline variable // in your header file What does your TI compiler think about that? -- Best regards, Andrey |
| Lynn McGuire <lynnmcguire5@gmail.com>: Oct 13 09:55PM -0500 On 10/12/2022 9:59 PM, Andrey Tarasevich wrote: > static std::string msg; > skip:; > At 'skip' you will see non-constructed (and therefore unusable) 'msg'. Thanks ! Lynn |
| Lynn McGuire <lynnmcguire5@gmail.com>: Oct 13 09:56PM -0500 On 10/12/2022 9:59 PM, Ben Bacarisse wrote: >> after a goto ? > You can't have a goto and a matching label that might skip over an > initialisation. The same applies to non-constructed POD types too. Thanks ! What is a POD type ? Lynn |
| "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 13 08:11PM -0700 On 10/13/2022 7:56 PM, Lynn McGuire wrote: >> initialisation. The same applies to non-constructed POD types too. > Thanks ! > What is a POD type ? Plain Old Data. Iirc, there is a way to test for it: https://en.cppreference.com/w/cpp/types/is_pod |
| Lynn McGuire <lynnmcguire5@gmail.com>: Oct 13 10:45PM -0500 On 10/13/2022 10:11 PM, Chris M. Thomasson wrote: >> What is a POD type ? > Plain Old Data. Iirc, there is a way to test for it: > https://en.cppreference.com/w/cpp/types/is_pod Thanks ! And that method is deprecated already. Lynn |
| "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 13 08:54PM -0700 On 10/13/2022 8:45 PM, Lynn McGuire wrote: >> Plain Old Data. Iirc, there is a way to test for it: >> https://en.cppreference.com/w/cpp/types/is_pod > Thanks ! Cool. > And that method is deprecated already. God damn it! Sorry Lynn. ;^o |
| "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 13 08:55PM -0700 On 10/13/2022 8:54 PM, Chris M. Thomasson wrote: > Cool. >> And that method is deprecated already. > God damn it! Sorry Lynn. ;^o Iirc, POD in C++ is akin to a struct in C. |
| Gawr Gura <gawrgura@mail.hololive.com>: Oct 14 04:41AM On Thu, 13 Oct 2022 20:54:38 -0700, Chris M. Thomasson wrote: > Cool. >> And that method is deprecated already. > God damn it! Sorry Lynn. ;^o You can still get this information with std::is_trivial and std::is_standard_layout. Perhaps template <typename T> constexpr bool is_pod_v = std::is_trivial_v<T> && std::is_standard_layout_v<T>; |
| Andrey Tarasevich <andreytarasevich@hotmail.com>: Oct 14 01:07AM -0700 On 10/13/2022 8:45 PM, Lynn McGuire wrote: >> https://en.cppreference.com/w/cpp/types/is_pod > Thanks ! > And that method is deprecated already. It is deprecated because there's no such thing as "POD" in C++ anymore. After C++11 the language opted for a finer granularity in classifying its types. POD turned out to be too coarse. -- Best regards, Andrey |
| Ralf Fassel <ralfixx@gmx.de>: Oct 14 11:53AM +0200 * "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> | On 10/13/2022 8:45 PM, Lynn McGuire wrote: | > On 10/13/2022 10:11 PM, Chris M. Thomasson wrote: | >> On 10/13/2022 7:56 PM, Lynn McGuire wrote: | >>> On 10/12/2022 9:59 PM, Ben Bacarisse wrote: | >>>> Lynn McGuire <lynnmcguire5@gmail.com> writes: | >>> What is a POD type ? | >> | >> | >> Plain Old Data. Iirc, there is a way to test for it: | >> | >> https://en.cppreference.com/w/cpp/types/is_pod | > | > Thanks ! | Cool. | > | > And that method is deprecated already. | God damn it! Sorry Lynn. ;^o For an alternative, see https://stackoverflow.com/questions/48225673/why-is-stdis-pod-deprecated-in-c20 R' |
| scott@slp53.sl.home (Scott Lurndal): Oct 14 01:48PM >Cool. >> And that method is deprecated already. >God damn it! Sorry Lynn. ;^o Deprecated doesn't mean it won't still work for the rest of time... |
| Richard Damon <Richard@Damon-Family.org>: Oct 14 01:38PM -0400 On 10/14/22 9:48 AM, Scott Lurndal wrote: >> God damn it! Sorry Lynn. ;^o > Deprecated doesn't mean it won't still work for the > rest of time... deprecated mean it MIGHT not work under some future Standard. It is an advanced warning that it might be removed (but no promise that it will). |
| scott@slp53.sl.home (Scott Lurndal): Oct 14 05:53PM >> rest of time... >deprecated mean it MIGHT not work under some future Standard. It is an >advanced warning that it might be removed (but no promise that it will). And even if it is removed from the standard, it's likely that compilers will continue to support it... |
| Juha Nieminen <nospam@thanks.invalid>: Oct 14 05:54AM > It is very rare that "as portable as possible" is a realistic > specification. It happens, but it is not common. "Not common" does not mean "you shouldn't care", when you are writing a library that could potentially be used in more exotic architectures, such as the one mentioned in this thread. For example if you are writing, say, a small library that calculates hashes or checksums using a particular algorithm. It's not at all unrealistic that such a library could have uses in these more exotic microcontrollers (as microcontrollers are often used in embedded systems that handle data somehow, and might be interested in calculating things like checksums and hashes). And it is quite likely that such an algorithm might care about bit sizes. |
| Paavo Helde <eesnimi@osa.pri.ee>: Oct 14 09:16AM +0300 14.10.2022 08:54 Juha Nieminen kirjutas: > systems that handle data somehow, and might be interested in calculating > things like checksums and hashes). And it is quite likely that such > an algorithm might care about bit sizes. True, but for really supporting such exotic platforms one would need to run tests on these platforms (or at least in an emulator) during the development and potentially also later if anything changes. Software without tests is just a work of literature. And testing for such exotic platforms might easily multiply the costs of the project by a large factor. That does not mean one should not attempt to write code in a reasonably generic way, but there are some limits. |
| Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Oct 14 12:17AM -0700 On Friday, October 14, 2022 at 6:54:49 AM UTC+1, Juha Nieminen wrote: > systems that handle data somehow, and might be interested in calculating > things like checksums and hashes). And it is quite likely that such > an algorithm might care about bit sizes. I have the code for an encryption algorithm here, which I got off Github. The code is a single C++ header file that's supposed to be fully-portable. I want to take this header file and add it to my own 'universal header file' which will be used on microcontrollers and desktop PC's. I've looked through the encryption header file, and I see that they use "unsigned short" for anything up to 65 thousand, and then "unsigned long" for anything up to 4 billion, so that's fine. There are however a few lines I have to tweak, such as the following: p[i] = p[i - 1] << 4u; I need to make that: p[i] = (p[i-1] << 4u) & 0xF0; To be honest, discovering a computer-and-compiler-combo with a CHAR_BIT != 8 like this is quite an experience for me. It's like I'm a biologist who's been dealing with carbon-based life forms all his life, and they've flown me in a silicon-based life form from Mars and I have it under my microscope. Twenty years is a long time to have CHAR_BIT invariably equal to 8. I'm re-writing the encryption code so that it deals in 32-Bit chunks, and I'm using 'uint_least32_t' for that purpose just in case there isn't a 32-Bit type. |
| David Brown <david.brown@hesbynett.no>: Oct 14 03:27PM +0200 On 13/10/2022 23:30, Mr Flibble wrote: >> because you'd never use such things (other than std::array). > Why just std::array? You could use any container with a suitable > allocator. Yes, it is always /possible/. But the complications and effort involved is unlikely to be worth the effort, and you'd still end up with something taking a massive amount of code space. (With "massive" being relative to the small code memories of such systems.) It's not uncommon in my coding to build up a few lists at the startup of the system - lists of "run" functions or software timers, etc. Modules might register such callbacks or functions when initialised. In "big system" C++, you might just use a vector for that - adding your timer objects to your vector as needed. It's simple and easy in the code. But in a resource-constraint embedded system, where efficiency of code space, ram space and run-time is important (though run-time efficiency is usually less important for startup code), that's not what you would do. You make your timer class have the required list link pointers in the class, have each registering function declare their timer object with static lifetime, and your registration function links them together. There's no doubt that this takes a bit more effort to write than an off-the-shelf std::vector. But it is vastly simpler than faffing around making your own allocator, avoids the use of any kind of dynamic memory (using neither the standard heap nor a home-made allocation system), and pulls in a tiny fraction of the amount of library code. std::array<> is free - it's just a nice wrapper around a plain C-style array. |
| David Brown <david.brown@hesbynett.no>: Oct 14 03:33PM +0200 On 14/10/2022 09:17, Frederick Virchanza Gotham wrote: >> things like checksums and hashes). And it is quite likely that such >> an algorithm might care about bit sizes. > I have the code for an encryption algorithm here, which I got off Github. You'll want to check that code anyway. There's a lot of excellent code on Github, but there's also a lot of rubbish or questionable code masquerading as good code. If reliable encryption is important, you have to be very careful - remember that testing can only show the presence of bugs, not their absence. > p[i] = (p[i-1] << 4u) & 0xF0; > To be honest, discovering a computer-and-compiler-combo with a CHAR_BIT != 8 like this is quite an experience for me. It's like I'm a biologist who's been dealing with carbon-based life forms all his life, and they've flown me in a silicon-based life form from Mars and I have it under my microscope. Twenty years is a long time to have CHAR_BIT invariably equal to 8. > I'm re-writing the encryption code so that it deals in 32-Bit chunks, and I'm using 'uint_least32_t' for that purpose just in case there isn't a 32-Bit type. If the code works fine even if "uint_least32_t" is not 32-bit, then perhaps "uint_fast32_t" would be better - even though it is 64-bit on some systems. (And if it won't be correct on such systems, then you need uint32_t anyway.) |
| Mr Flibble <flibble@reddwarf.jmc.corp>: Oct 14 02:47PM +0100 On Fri, 14 Oct 2022 15:27:13 +0200 > library code. > std::array<> is free - it's just a nice wrapper around a plain > C-style array. List link pointers? Again there is no reason to not use std::list with a suitable allocator even on such resource constrained hardware and I disagree that the resultant text size and ram usage would be any worse than anything you could come up with by hand. /Flibble |
| Muttley@dastardlyhq.com: Oct 14 02:58PM On Fri, 14 Oct 2022 14:47:46 +0100 >a suitable allocator even on such resource constrained hardware and I >disagree that the resultant text size and ram usage would be any worse >than anything you could come up with by hand. If the memory layout is hard coded at boot time why even bother pulling in std::list or any kind of container as you don't need their generic functionality which will almost certainly waste EEPROM space. With embedded development you often literally have to worry about every byte you use both in ROM and RAM and whether the mainloop is going to be fast enough to do its job. |
| JiiPee <kerrttuPoistaTama11@gmail.com>: Oct 14 07:29AM +0300 On 14/10/2022 00:36, Mike Terry wrote: > and > #pragma warning( pop ) > to save/restore the current warning settings. thanks. I ll save this and can try it :). |
| "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 14 12:33AM -0700 On 10/13/2022 2:27 PM, JiiPee wrote: > "Please, define "not necessarily"?" > I mean, likely the code does not need change. so its only a warning > coming but does not need action. Can you isolate the code in a shared or static library with an API interface and label it version_original or something? Perhaps, stuff it under its own namespace? There are some tricks wrt introducing new functions on existing code in C. |
| Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Oct 14 01:43AM -0700 On Wednesday, October 12, 2022 at 9:49:01 PM UTC+1, JiiPee wrote: > a = static_cast<short>(v.size()); > but if we have hundreds of those lines, how would you fix this? Place a > static cast in all of them? Of create some helper funktion to do this? Try this regex: https://regex101.com/r/5tsXx3/1 |
| 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