- Transitioning... - 10 Updates
- Rust has the same memory problem as C and C++ - 6 Updates
- std::filesystem::copy_options::overwrite_existing throws - 3 Updates
red floyd <myob@its.invalid>: May 01 09:45AM -0700 I have a codebase written in c90. We have a once in a lifetime opportunity to refactor, rearchitect, and rewrite. As such, we are going to rewrite in C++. Here's my issue. We have two target platforms, one of which has only a C++03 compiler, the other has a C++11 compiler as well. Yes I know that both are old language standards, but it's what we have to work with. The platform with only C++03 support is old, and may stop being supported. We're trying to decide whether to write in C++11 and forget the older platform, or use C++03 and support both, and later transition to C++11. We know the LOE to transition to C++. The question is, what is the effort to transition a C++03 code base to C++11, including the use of more modern features to enhance code robustness? I know that you can throw C++03 at a C++11 compiler and it will build, but as this is a one time only deal, we want to do things as right as possible the first time. Any opinions on the level of effort for a "proper" 03 => 11 transition? Suggestions, etc, are also welcome. Thanks, red floyd |
Paavo Helde <eesnimi@osa.pri.ee>: May 01 08:43PM +0300 01.05.2020 19:45 red floyd kirjutas: > I have a codebase written in c90. We have a once in a lifetime > opportunity to refactor, rearchitect, and rewrite. As such, we > are going to rewrite in C++. Having an opportunity is not a sufficient reason to justify a rewrite which will inevitable introduce new bugs and destabilize the code base (unless you have a pretty decent unit test coverage). A valid reason for a rewrite would be a need to significantly expand the system later. For that it would help if the existing codebase is written in ways compatible with extensions (abstract base classes, std::function callbacks, etc). C++03 is actually pretty good for building such infrastructure. However, if you are going to phase out the old platform anyway soon, will it benefit at all from this rewrite? If not, then it should be left to use the C solution. So, the correct answer depends on the actual reason of the rewrite which you have not disclosed. If this reason is valid also for the old platform you should rewrite the codebase in C++03 and move on to C++11 later. If the reasons of rewrite do not apply to the old platform you should leave the old platform to the existing C solution and upgrade the rest of the system directly to C++11 (or later) as C++ programming has become much more convenient and safer with C++11. |
red floyd <myob@its.invalid>: May 01 11:04AM -0700 On 5/1/2020 10:43 AM, Paavo Helde wrote: > should leave the old platform to the existing C solution and upgrade the > rest of the system directly to C++11 (or later) as C++ programming has > become much more convenient and safer with C++11. Thanks, Paavo, I understand your concerns, and am normally a huge proponent of the "if it ain't broke, don't fix it" approach. However, I believe that it is "broke". The platforms currently share a common codebase. The code has become so fragile, to the point that we are afraid to fix any bugs, because we are worried that touching $X will break $Y. It's an accumulation of fifteen years of ad hoc patches. This is ancient legacy code. We also have some internal framework code that we use, but it's very rudimentary, and doesn't support all the features we need, which has led to some very ugly and fragile hacks. The latest version of the framework, which includes fully fleshed out versions of the features that we hacked, requires C++. In all fairness to our management, they are giving us a reasonable amount of time to do the up front design work. The main question here was assuming that we are redesigning in C++ -- which, from signs given by management, appears to be a fait accompli -- Is it worth it to design in C++03, and later migrate to C++11, when the users of the older platform have migrated to the newer platform? What are people experiences in moving from C++03 to C++11 (or any modern variant), and what is the level of effort involved? -- red floyd |
Jorgen Grahn <grahn+nntp@snipabacken.se>: May 01 06:44PM On Fri, 2020-05-01, red floyd wrote: ... > users of the older platform have migrated to the newer platform? What > are people experiences in moving from C++03 to C++11 (or any modern > variant), and what is the level of effort involved? As far as I'm concerned, all the basic, useful features are in C++98. My C++11 code mostly adds 'auto' and lambdas, but these don't affect the basic design. I'm more likely to use std::find_if due to the easy access to functors (lambdas), and less likely to add a lot of typedefs due to auto. Smart pointers (unique_ptr; shared_ptr if you need those) is another thing, but as with many library features you can get it from Boost. It also depends on what the programmers are comfortable with. Maybe you all write C++17 code and would hate to step back in time 20 years? Or maybe learning how to use a new C++ dialect well would distract from the porting work? /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Paavo Helde <eesnimi@osa.pri.ee>: May 01 09:48PM +0300 01.05.2020 21:04 red floyd kirjutas: > fragile, to the point that we are afraid to fix any bugs, because we are > worried that touching $X will break $Y. It's an accumulation of fifteen > years of ad hoc patches. This is ancient legacy code. I would say the most urgent need for you is to develop a comprehensive automatic test suite. It would help with avoiding $X breaking $Y, it would help (a lot!) when rewriting the code in C++, and it will help (a lot!) when later developing the system further. I know it does not sound pleasant to put all developers (QA, if you have one, is probably not qualified enough) writing unit/integration tests for a couple of months, instead of writing new shiny C++ code, but this is actually the only way to come out of such a situation and save money in the long run. > which, from signs given by management, appears to be a fait accompli -- > Is it worth it to design in C++03, and later migrate to C++11, when the > users of the older platform have migrated to the newer platform? This depends on whether these people need feature $Y before migrating to the newer platform. > What > are people experiences in moving from C++03 to C++11 (or any modern > variant), and what is the level of effort involved? You actually don't migrate the codebase from C++03 to C++11, this is not needed for anything. You just starting writing the new code (and any local refactoring of old code) with C++11 means as soon as the build process has switched on -std=c++11 (or equiv). So in this sense the transition should be smooth. In C++03, beware to not use things removed in later C++ standards like throw specifications, 'register' keyword, std::bind1st, etc. |
Paavo Helde <eesnimi@osa.pri.ee>: May 01 09:52PM +0300 01.05.2020 21:48 Paavo Helde kirjutas: > In C++03, beware to not use things removed in later C++ standards like > throw specifications, 'register' keyword, std::bind1st, etc. Oh, and avoid std::auto_ptr of course. Use Boost smart pointers or develop your own, that's not so complicated. |
Jorgen Grahn <grahn+nntp@snipabacken.se>: May 01 09:17PM On Fri, 2020-05-01, Paavo Helde wrote: ... > I know it does not sound pleasant to put all developers (QA, if you have > one, is probably not qualified enough) writing unit/integration tests > for a couple of months, instead of writing new shiny C++ code, Seconded. You feel so stupid when you know how you want to refactor the code, but have no way to tell if it still works afterwards. > but this is actually the only way to come out of such a situation > and save money in the long run. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
"Öö Tiib" <ootiib@hot.ee>: May 01 02:18PM -0700 On Friday, 1 May 2020 19:45:00 UTC+3, red floyd wrote: > only a C++03 compiler, the other has a C++11 compiler as well. > Yes I know that both are old language standards, but it's what > we have to work with. Platforms that lag behind do often have some quirks in their implementations of those older standards too. Common code can be fine but some trick (like used in boost) may refuse to compile or act in non-conforming manner. > time. > Any opinions on the level of effort for a "proper" 03 => 11 transition? > Suggestions, etc, are also welcome. There were next to none silently breaking changes between C++03 and C++11. Vast majority of C++03 code did build and run as C++11 too. There can be some undefined behaviors that start to manifest differently, but it is generally good that these will be noticed. Additionally there is Clang-Tidy that actively suggests what to refactor in C++03 code. So I think that rewriting C90 -> C++03 is large effort because the idioms and design strategies of those languages are different. Migrating C++03 -> C++11 is order of magnitude smaller effort. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: May 01 02:40PM -0700 > time. > Any opinions on the level of effort for a "proper" 03 => 11 transition? > Suggestions, etc, are also welcome. What if you transition directly from C90 to C++11 and just don't support the new codebase on the old platform? Can you continue supporting only the old C codebase on the old platform until it's retired, while using the new C++11 codebase on the new platform? You know the old C90 code still works; is that good enough for *temporary* support? On the other hand, supporting two different codebases simultaneously isn't going to be free. On the gripping hand, having the old and new codebases in production use at the same time might help weed out inconsistencies. How sure are you that the old target platform is really going away? Is there a risk that you'd be stuck supporting the C90 codebase indefinitely? -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
red floyd <myob@its.invalid>: May 01 03:52PM -0700 On 5/1/2020 2:17 PM, Jorgen Grahn wrote: > the code, but have no way to tell if it still works afterwards. >> but this is actually the only way to come out of such a situation >> and save money in the long run. That's one of the pluses of a refactor on this scale. For historical reasons, and then because of the high coupling factor from the patches, it was really impossible to have an automated unit test suite. By refactoring on this scale, we can write the unit tests as we go. A little more historical background, this was a proof-of-concept that marketing grabbed and said "OK, it's the product". So it didn't have the in-depth design and review that it would today. |
Richard Damon <Richard@Damon-Family.org>: Apr 30 08:43PM -0400 On 4/30/20 5:18 PM, Keith Thompson wrote: > int *class = malloc(sizeof 'A'); > } > would be worth the implementation effort. Wouldn't that be illegal as C code, as C requires file scope initializers to be constants, so we never get to the type of 'A'; Now make that extern "C" { extern int foo[sizeof 'A']; } and you have a different problem. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Apr 30 07:00PM -0700 >> would be worth the implementation effort. > Wouldn't that be illegal as C code, as C requires file scope > initializers to be constants, so we never get to the type of 'A'; Yes, good point. Make it extern "C" { int class = sizeof 'A'; } -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
Juha Nieminen <nospam@thanks.invalid>: May 01 07:26AM > in C. Since it is C++ that wants to include C headers, and not the > other way around, it is C++ that should more of the heavy lifting > needed to get that to happen. I'm not sure that solves the problem I presented. Suppose you have something like this in a typical C header: //--------------------------------------------------- struct Data { int value1; double value2; float table[10]; }; double handleData(const Data* data); //--------------------------------------------------- (I omitted the typical "#ifdef __cplusplus extern "C"" part for brevity.) In the C++ code you need to be able to call that function, and in order to do that you need a way to create and handle instances of that struct. This could become difficult if there was a complete incompatibility between C++ and C. Suddenly you couldn't, possibly, instantiate that struct, initialize its members, etc etc, if the syntax (and perhaps even semantics) to do so would be wildly different in C++. You would need some kind of interoperatibility syntax between C data types and C++ data types and code. Also consider how some C library headers may declare preprocessor defines that have something more than just integer or string literals. They may contain "inline" code. This code would be inserted into your C++ code if you use those macros. Obviously if C++ syntax were wildly different from C syntax, it would completely exclude the possibility of using such macros in such headers. |
Juha Nieminen <nospam@thanks.invalid>: May 01 07:31AM >> Of course nowadays we can declare it as 'inline' which solves the problem, >> but that has to be explicitly specified, and it needs compiler support. > What's difference if `inline`? If I understand correctly, an 'inline' variable will be dealt with the same way as an 'inline' function: If it ends up being actually instantiated (ie. not actually inlined) and thus may appear in more than one object file, the linker will be instructed to just choose one of those instances and discard the rest. All uses of that object or function will refer to that one singular instance (rather than multiple ones). (This means that, for example, a pointer to the object/function will always be the same accross the entire program, rather than every compilation unit getting its own separate pointer value.) |
Paavo Helde <eesnimi@osa.pri.ee>: May 01 10:31AM +0300 01.05.2020 02:19 James Kuyper kirjutas: > you need to more precisely specify what you mean by "C semantics". > If the C++ standard were modified as you describe, how could such code > be re-written? +1 Restricting extern "C" to pure C would make it pretty hard to write shared library plugins in C++ as currently extern "C" is the only way to make standard and predictable function names for shared library symbol lookup. |
David Brown <david.brown@hesbynett.no>: May 01 06:24PM +0200 On 01/05/2020 09:31, Juha Nieminen wrote: > (This means that, for example, a pointer to the object/function > will always be the same accross the entire program, rather than > every compilation unit getting its own separate pointer value.) A vital point to mention is that all definitions of the object must be the same, so that it doesn't matter which of the objects the linker uses and which it discards. (Again, just like inline functions.) The addition to the language is so that you can conveniently put large object definitions (whether const or not) in a header without needing an accompanying .cpp file or playing tricks with templated functions with static variables. |
Ralf Goertz <me@myprovider.invalid>: May 01 08:19AM +0200 Am Thu, 30 Apr 2020 22:58:54 +0300 > > really be a bug? > FWIW, compiling this program with my Cygwin gcc 9.3.0 in Windows > works as expected (copies the file). Interesting. I used msys2 64bit. So this is more likely to be an msys2 bug then? > (including non-obvious ones like virus scanners) so that they cannot > be deleted (though in this case the error message should probably be > something like "Access denied"). Yeah I know that, but this is not the case here. I used $ touch foo $ fs_copy $ fs_copy with fs_copy being the program above and its second execution threw. (Also in a powershell btw.) Then after deleting "foo" and "bar" I used $ touch foo $ cp foo bar $ cp foo bar which worked fine. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 01 08:28AM +0200 On 01.05.2020 08:19, Ralf Goertz wrote: > $ cp foo bar > $ cp foo bar > which worked fine. Is it /consistently/ reproducible? During the last year or so Microsoft has introduced a bug-nest somewhere in the high level file system interfaces, so that some operations such as obtaining directory listings, involve inordinately long pauses -- usually one long pause (which is not disk spin-up) at the start. They have a history of introducing such pauses for Odin knows what reason, e.g. for listing network connections via `netstat`, or listing open file handles via `openfiles`, or for that matter, for moving, via Explorer, a directory from one place to another place on the same drive, but via a logical drive (which shouldn't matter, it should be instant anyway). Historically it seems to me, but I /could/ be wrong, that these artifical slow-downs have to do with some manager or group of managers at Microsoft saving himself/themselves work and face by sabotaging the system instead of being responsible for a fix of something. - Alf |
Ralf Goertz <me@myprovider.invalid>: May 01 08:43AM +0200 On Fri, 1 May 2020 08:28:51 +0200 > > $ cp foo bar > > which worked fine. > Is it /consistently/ reproducible? Yes. I noticed it about a month ago after porting my linux program to windows. The program is in heavy use by my colleagues and they always have to delete the files before starting it. It was only yesterday that I started to investigate it further. > work and face by sabotaging the system instead of being responsible > for a fix of something. > - Alf I wouldn't know but I doubt it. As I said there is no problem copying and overwriting files by other means. |
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