- "C++ on the Move" by Darryl K. Taft - 4 Updates
- reference to reference (Type &&) - 6 Updates
- why additional \r before each \r\n - 2 Updates
- Found a use case for `const` by value return, a shared queue - 7 Updates
- Functions and Global Variables defined in Libraries - 2 Updates
Lynn McGuire <lynnmcguire5@gmail.com>: Mar 07 03:38PM -0600 "C++ on the Move" by Darryl K. Taft https://thenewstack.io/c-on-the-move/ "While the C++ programming language seems to be as popular as ever, efforts to move it forward are ongoing both inside the ISO C++ steering committee as well as other projects." Lynn |
legalize+jeeves@mail.xmission.com (Richard): Mar 07 10:08PM [Please do not mail me a copy of your followup] Lynn McGuire <lynnmcguire5@gmail.com> spake the secret code >"C++ on the Move" by Darryl K. Taft A ho-hum article IMO. You've posted better :). -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Lynn McGuire <lynnmcguire5@gmail.com>: Mar 07 04:25PM -0600 On 3/7/2023 4:08 PM, Richard wrote: > <tu8at1$ijm1$1@dont-email.me> thusly: >> "C++ on the Move" by Darryl K. Taft > A ho-hum article IMO. You've posted better :). I was curious in what people thought of the last paragraph, ""Now bring Rust to the table — a language well-suited for the low-level programming that C++ typically dominates, but with built-in memory safety and other modern features," Campbell said. "When luminaries like Mark Russinovich are saying things like ['…halt starting any new projects in C/C++ and use Rust…'], C++ must evolve or be left behind. The question is, at what price?" he said." https://twitter.com/markrussinovich/status/1571995117233504257?lang=en Thanks, Lynn |
legalize+jeeves@mail.xmission.com (Richard): Mar 07 11:10PM [Please do not mail me a copy of your followup] Lynn McGuire <lynnmcguire5@gmail.com> spake the secret code >>> "C++ on the Move" by Darryl K. Taft >> A ho-hum article IMO. You've posted better :). >I was curious in what people thought of the last paragraph, [...] IMO they found someone with some credibility to say something spicy in order to get some rage clicks for their article. That isn't to say that the safety aspects of C++ should be ignored; but honestly 25 years ago I taught my team the Standard Library containers and all our memory leaks and crashes disappeared. The argument that C++ is only as safe as the habits and disciplines of your team is still true. Herb Sutter's cpp2 is a better way to address that than Rust, C#, Java, Carbon or whatever new language that is going to "kill C++" this week. A weak developer can code resource leaks in any language. I've seen it done in Java and C# many times by my coworkers. A weak C++ developer will blame std::vector<> as "buggy" when in reality the types they put into the container didn't satisfy the Copyable requirement. Every time some non-C++ programmer complains about how C++ is "unsafe" and I ask them to show me an example, they show me C code. It's fine to criticize C++ but at least know what you're talking about when you do it. If I started bitching about Java and when asked to put up or shut up, I started showing JavaScript, people would rightly laugh at me. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
James Kuyper <jameskuyper@alumni.caltech.edu>: Mar 06 07:48PM -0500 On 3/6/23 17:22, MarioCPPP wrote: ... > I have to understand what is a MOVE SEMANTIC. > In my old-styled mind move IS copying (and deleting the > original object). Only when necessary. What the semantics of moving are is up to the implementor of the relevant special functions. A typical example is when an object doesn't contain the actual data, but only a pointer to the data. A copy constructor would copy the data that was pointed at, and then put a pointer to the copied data in the new object. The destructor would deallocate the memory the data was stored in. A move constructor, on the other hand, would move the pointer from the existing object to the new one, replacing the pointer in the existing object with a null pointer to indicate that it no longer had any data. The data that was pointed at would remain untouched. As a result, a move can be much faster than a copy followed by a delete. The only point in creating a move constructor is if it can, indeed, be faster than a copy followed by a delete. I don't know anywhere near as much about r-value references as other people, so I'll let them try to explain how that is connected. |
MarioCPPP <NoliMihiFrangereMentulam@libero.it>: Mar 07 12:19PM +0100 On 07/03/23 01:48, James Kuyper wrote: > followed by a delete. > I don't know anywhere near as much about r-value references as other > people, so I'll let them try to explain how that is connected. seems really intresting (even if I am still unable to guess a full example). Well your explanation was actually closer to my starting point and so more useful to me. :D -- 1) Resistere, resistere, resistere. 2) Se tutti pagano le tasse, le tasse le pagano tutti MarioCPPP |
Malcolm McLean <malcolm.arthur.mclean@gmail.com>: Mar 07 03:48AM -0800 On Monday, 6 March 2023 at 22:22:52 UTC, MarioCPPP wrote: > ... my fault !) > But I still cant'imagine its use. > I have to understand what is a MOVE SEMANTIC. Essentially it is this. struct foo { unsigned char *data; size_t N; }; void deep_copy(struct foo *dest, const struct foo *source) { free(dest->data); dest->data = malloc(source->N); memcpy(dest->data, source->data, source->N): dest->N = source->N; } If N is large, this is quite expensive. void move(struct foo *dest, struct foo * source) { unsigned char *temp = dest->data; dest->data = source->data; source->data = temp; size_t tempN = dest->N dest->N = source->N; source->N = tempN; } This is only a few machine instructions. But source is no longer a constant, it is altered by the operation. It's left in a valid but unusable state. In fact it is set to the old value of dest, but this isn't part of the specification and isn't guaranteed. All C++ move semantics is is wrapping this idea in nice syntax. |
"Öö Tiib" <ootiib@hot.ee>: Mar 07 04:30AM -0800 On Tuesday, 7 March 2023 at 13:48:21 UTC+2, Malcolm McLean wrote: > void move(struct foo *dest, struct foo * source) You wrote a swap named as "move". That can confuse. Swap may fit with most loose requirements of move but usually is not used as that. Other purpose of move are objects that represent something that can not (or should not) be copied. Like file descriptors, sockets or threads. There move is used as way of passing of ownership. |
Muttley@dastardlyhq.com: Mar 07 03:58PM On Tue, 7 Mar 2023 03:48:11 -0800 (PST) >All C++ move semantics is is wrapping this idea in nice syntax. Nice syntax but leaving the danger as you say of the source in a potentially unusable state. IMO move() is best avoided unless you really know what you're doing but unfortunately a lot of people think its just a quick copy without realising the consequences. |
Paavo Helde <eesnimi@osa.pri.ee>: Mar 08 12:10AM +0200 >> All C++ move semantics is is wrapping this idea in nice syntax. > Nice syntax but leaving the danger as you say of the source in a potentially > unusable state. This exact danger is why we have rvalue references in the language, so that dangerous bindings are mostly avoided. Either there is a genuine rvalue whose final state would not be important anyway, or we use std::move() to explicitly declare we do not care about the final state of the object. > IMO move() is best avoided unless you really know what you're > doing but unfortunately a lot of people think its just a quick copy without > realising the consequences. Here you are right, rvalue references should be used only by people who know what they are doing, similar to any other feature in C++. |
Paavo Helde <eesnimi@osa.pri.ee>: Mar 07 08:34AM +0200 06.03.2023 20:35 Jivanmukta kirjutas: > You are right. I used macro because I had 2 different definitions for > Linux and for Windows. Now I have identical definitions and macro is not > necessary. But you still have different file contents in Windows and in Linux, because of the "helpful" translation of line feeds in text mode. This just complicates things and is not needed for anything because nowadays the files are commonly shared over the network and can easily end up on a "wrong platform". Suggesting to always use binary mode file streams and '\n' newlines when writing files, to get predictable and fixed behavior. Nowadays even Notepad copes with the Unix-style newlines, so there should be no need to have any \r\n newlines around. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Mar 07 12:17PM -0800 > 06.03.2023 20:35 Jivanmukta kirjutas: [...] > when writing files, to get predictable and fixed behavior. Nowadays > even Notepad copes with the Unix-style newlines, so there should be no > need to have any \r\n newlines around. Another approach is to use the native encoding for each operating system. Many (but not all) Unix/Linux tools handle files with Windows-style line endings. Yes, it can be annoying, but it's workable. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for XCOM Labs void Void(void) { Void(); } /* The recursive call of the void */ |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Mar 06 03:29PM -0800 On 3/5/2023 8:52 PM, Bonita Montero wrote: >> There is nothing wrong with using a race-detector. ... > And there's noting wrong to buy a supercomputer to proof that > one plus one is two. Huh? I think you missed my point. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Mar 06 03:42PM -0800 On 3/5/2023 8:52 PM, Bonita Montero wrote: >> There is nothing wrong with using a race-detector. ... > And there's noting wrong to buy a supercomputer to proof that > one plus one is two. for instance.. Some code that is "trivial" to me, still deserved to be implemented in Relacy first: https://pastebin.com/raw/f71480694 ;^) |
Bonita Montero <Bonita.Montero@gmail.com>: Mar 07 06:44AM +0100 > FFS, the wait() was in the thread queue. It doesnt make sense at all. > Like all your code, its far too complicated for the simple job it has to do. This is a reusable component which is much easier to use than what you have shown. |
Muttley@dastardlyhq.com: Mar 07 09:31AM On Tue, 7 Mar 2023 06:44:31 +0100 >Am 06.03.2023 um 18:07 schrieb Muttley@dastardlyhq.com: >> FFS, the wait() was in the thread queue. >It doesnt make sense at all. It makes a lot more sense than any example code you'eve ever written. But if you don't understand how condition variables control threads then fair enough. >> Like all your code, its far too complicated for the simple job it has to do. >This is a reusable component which is much easier to use >than what you have shown. I can't imagine anyone using it in their code. |
Bonita Montero <Bonita.Montero@gmail.com>: Mar 07 02:45PM +0100 > It makes a lot more sense than any example code you'eve ever written. But > if you don't understand how condition variables control threads then fair > enough. As far as you can see from my code I know how producer-consumer-patterns are handled in C++. As far as I can see from your code you don't. >> This is a reusable component which is much easier to use >> than what you have shown. > I can't imagine anyone using it in their code. You can't say sat because you're too stupid to understand the code. |
Muttley@dastardlyhq.com: Mar 07 03:59PM On Tue, 7 Mar 2023 14:45:41 +0100 >Am 07.03.2023 um 10:31 schrieb Muttley@dastardlyhq.com: >> I can't imagine anyone using it in their code. >You can't say sat because you're too stupid to understand the code. Producer-consumer is a simple solved problem. No one would use your dogs dinner if you paid them. |
Bonita Montero <Bonita.Montero@gmail.com>: Mar 07 05:37PM +0100 > Producer-consumer is a simple solved problem. > No one would use your dogs dinner if you paid them. The easiest way is to use pre-defined components for that. I've shown such a component which is much easier to use than handling this manually. You didn't even understood that this is a reusable component. |
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Mar 07 03:49AM -0800 Let's say we have a program that links with a library that exports a global variable and a function. So the library looks like this: int lib_global_variable = 0; void Func(void) { } The main program has the following declarations: extern int lib_global_variable; extern void Func(void); The program links fine and runs fine if we give the linker "-L. -lname_of_library". If we use the program "nm" on the main executable and grep for "lib_global_variable" and "Func", we see that both are listed as undefined symbols: U lib_global_variable U _Z7LibFuncv If we use 'readelf' on the main executable and grep for the same two symbols, we see: 000000003fc8 000700000006 R_X86_64_GLOB_DAT 0000000000000000 lib_global_variable + 0 000000004038 000900000007 R_X86_64_JUMP_SLO 0000000000000000 _Z7LibFuncv + 0 7: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND lib_global_variable 9: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _Z7LibFuncv 39: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND lib_global_variable 41: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _Z7LibFuncv I've been doing some testing and tinkering, and I've found that the strategy of using 'dlopen' at runtime to load a library works fine so long as the undefined symbol is listed under R_X86_64_JUMP_SLO. It doesn't work if the symbol is listed under R_X86_64_GLOB_DAT. Typically all undefined functions get listed under R_X86_64_JUMP_SLO, and all global variables get listed under R_X86_64_GLOB_DAT, however it is possible to get functions listed under R_X86_64_GLOB_DAT, and my strategy of using 'dlopen' doesn't work if the function is under R_X86_64_GLOB_DAT. It seems that GNU g++ by default puts the undefined function under R_X86_64_JUMP_SLO, however if you try to use the address of the function at all, for example: cout << (std::uintptr_t)(void*)LibFunc << endl; then the function gets moved to R_X86_64_GLOB_DAT, and then my strategy no longer works as 'dlopen' doesn't resolve the unresolved symbol. So I'd like to ask two questions: (1) Is the R_X86_64_JUMP_SLO category just for functions, or can we put global variables in there too? Is it possible to get 'dlopen' to resolve global variables? (2) Is there any way to stop the GNU g++ compiler from putting an undefined function in R_X86_64_GLOB_DAT? Can anyone suggest a good forum / mailing list where people would know a lot about this stuff? |
"Öö Tiib" <ootiib@hot.ee>: Mar 07 04:46AM -0800 On Tuesday, 7 March 2023 at 13:50:01 UTC+2, Frederick Virchanza Gotham wrote: > I've been doing some testing and tinkering, and I've found that the strategy of using 'dlopen' at runtime to load a library works fine so long as the undefined symbol is listed under R_X86_64_JUMP_SLO. It doesn't work if the symbol is listed under R_X86_64_GLOB_DAT. Then write exported getter function that goes to that R_X86_64_JUMP_SLO. Perhaps same can be achieved with dlsym(). |
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