- Threads on Windoze (was Re: Let's call the <=> operator "trike") - 10 Updates
- Group comp-lang-cpp - 3 Updates
- C++ Topics - 1 Update
- static constexpr with inner type doesn't compile - 7 Updates
- "+" and "-" for options set - 1 Update
David Brown <david.brown@hesbynett.no>: May 23 08:38AM +0200 On 23/05/18 00:03, Melzzzzz wrote: > You either use threads or processes. There is no point in using both > threads and fork, except as you noted when exec-ing from multi-thread > process. That's not /quite/ true. Large server programs can sometimes see advantages in having multiple processes, each of which has multiple threads. There may be no exec's involved - the parent process forks of multiple copy processes as needed. But child processes that spawn threads to do the actual work do not then fork - a given processes spawns either fork processes, or threads, but not both. (Except, as you say, for fork-exec for running independent programs.) |
boltar@cylonHQ.com: May 23 09:45AM On Tue, 22 May 2018 09:22:53 -0700 >> If I have to explain why its an ugly hack there's little point discussing it. >Nope. You're the one making an assertion without providing evidence. >Therefore you are the one who has to back up the assertion. Because starting up an entirely new process to pass a command line parameter that has to be parsed first then do an explicit jump or call to a particular function or location is utterly prehistoric compared to doing a switch() on the return value of fork(). Its aesthetically ugly and inefficient from a processor POV too. |
boltar@cylonHQ.com: May 23 09:54AM On Tue, 22 May 2018 21:42:40 +0200 >>What do you think fork() does? >It creates a copy of the current process, which in most use cases is >immediately disposed afterwards by calling one of the exec() variants. In most use cases? The shell, sure. Most other programs that use fork use it to undertake multi process processing. >Creating that unwanted copy may be expensive in the first place, >depending on the OS and MMU architecture. And it has ugly side-effects >for programs dealing with a lot of open handles, especially socket handles. Not at all. The open handles are a necessity for a lot of things and there is the SOCK_CLOEXEC option to automatically close sockets on an exec anyway. >running an arbitrary exe, passing over only explicitly specified >information through command line parameters, pipes, or environment >variables. Windows approach is a poor hack presumably because starting a new process from scratch is a lot simpler than effectively splitting one in 2 and having to manage everything that goes with that. |
Paavo Helde <myfirstname@osa.pri.ee>: May 23 02:22PM +0300 > Windows approach is a poor hack presumably because starting a new process > from scratch is a lot simpler than effectively splitting one in 2 and > having to manage everything that goes with that. And since when is a simpler way to do something called a "poor hack"? With fork+exec one needs to make sure that all the irrelevant open files, sockets and pipes (including the ones created by any third party libraries) have the proper FD_CLOEXEC flags attached. Yes, this is complicated and there are ugly hacks used to forcible close them. At least in Windows one needs to create inheritable handles explicitly and CreateProcess() function has the bInheritHandles parameter which gives another simple way to control it. But I guess this is too simple for your taste. |
Paavo Helde <myfirstname@osa.pri.ee>: May 23 02:38PM +0300 > function or location is utterly prehistoric compared to doing a switch() on > the return value of fork(). Its aesthetically ugly and inefficient from a > processor POV too. Unfortunately the trend appears to go toward multithreaded programs nowadays, and fork without exec cannot be used in multithreaded programs. At the same time, fork+exec involves the same "ugly" command line parameter parsing, plus other complications. So what you call "prehistoric" appears to be "trendy" now. Go figure. |
scott@slp53.sl.home (Scott Lurndal): May 23 01:26PM >Unfortunately the trend appears to go toward multithreaded programs >nowadays, and fork without exec cannot be used in multithreaded >programs. Sure it can. With care. Unixware even has a 'forkall()' system call that clones all the parent threads. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: May 23 04:46PM +0100 On Wed, 23 May 2018 13:26:46 GMT > Paavo Helde <myfirstname@osa.pri.ee> writes: [anip] > >programs. > Sure it can. With care. Unixware even has a 'forkall()' system call > that clones all the parent threads. I thought it was SunOS/Solaris which had forkall(). Are you sure about unixware? However, forkall() doesn't solve the issue. Before forkall()ing, the forking thread has the same problem of needing to synchronise with other threads. In the case of forkall() this is so that the other threads are in a state which allows them to be duplicated; in the face of fork() this is so that they are in a state which allows them not to be duplicated. Forkall() cannot be performed willy nilly without other threads' knowledge or consent, in particular with respect to side effects. Forkall()ing a process where a thread happens to be doing some IO is an obvious example of a disaster waiting to happen. forkall() just redistributes the problem. There is some discussion by Butenhof of this here in the context of the uselessness of pthread_atfork() (that was before our dear spammer drove the newsgroup concerned out of use): https://groups.google.com/d/msg/comp.programming.threads/ThHE32-vRsg/3j-YICgSQzoJ |
red floyd <dont.bother@its.invalid>: May 23 09:51AM -0700 On 5/23/2018 8:46 AM, Chris Vine wrote: >> that clones all the parent threads. > I thought it was SunOS/Solaris which had forkall(). Are you sure about > unixware? UnixWare was SVR4.x, which was also the basis for Solaris. Wouldn't be surprised if it had it. |
Paavo Helde <myfirstname@osa.pri.ee>: May 23 08:14PM +0300 On 23.05.2018 16:26, Scott Lurndal wrote: >> programs. > Sure it can. With care. Unixware even has a 'forkall()' system call > that clones all the parent threads. forkall() I can understand. But what do you mean by "with care"? Using pthread_atfork()? Seems pretty complicated. |
scott@slp53.sl.home (Scott Lurndal): May 23 05:25PM >> that clones all the parent threads. >forkall() I can understand. But what do you mean by "with care"? Using >pthread_atfork()? Seems pretty complicated. No, the threads within the application are coded to allow for the fact that at some point in time (controlled by the application itself) they will be forked. Controller/main thread tells other threads to prepare for fork, waits for them to check in, then forks. In the rare case that a third-party library which uses threads is linked into the application, then the third-party library would need to offer an api to quiesce its thread. Third party libraries that use threads are fairly rare. It's not like the fork()/forkall() calls are unexpected by the application. That said, I've been using threads since the late 80's, and have never encounted a use-case for forking a multithreaded app and not immediately calling exec(2). |
Jorgen Grahn <grahn+nntp@snipabacken.se>: May 23 07:10AM On Mon, 2018-05-21, Christiano wrote: > std-discussion and I want to suggest to isocpp.org to add comp-lang-cpp > here: > https://isocpp.org/std/forums Hasn't comp.lang.c++ always been unrelated to the commitee? Do you perhaps mean comp.std.c++? > This is being discussed here: > https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/pAL2dOe9MIk > I would like to know your opinion. Not interested, personally. (Also, it annoys me when people call C++ "cpp", since cpp is also the C preprocessor.) /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
legalize+jeeves@mail.xmission.com (Richard): May 23 02:53PM [Please do not mail me a copy of your followup] Jorgen Grahn <grahn+nntp@snipabacken.se> spake the secret code >(Also, it annoys me when people call C++ "cpp", since cpp is also the >C preprocessor.) Web thingies notoriously confuse + with ' ' because of URL encodings. -- "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> |
woodbrian77@gmail.com: May 23 10:11AM -0700 On Wednesday, May 23, 2018 at 2:10:13 AM UTC-5, Jorgen Grahn wrote: > > here: > > https://isocpp.org/std/forums > Hasn't comp.lang.c++ always been unrelated to the commitee? Others and I have made some informal proposals here. I hope that will continue. Comp.lang.c++.moderated was OK, but nothing to write home about. Brian Ebenezer Enterprises https://github.com/Ebenezer-group/onwards |
Pvr Pasupuleti <pvr.ram34@gmail.com>: May 23 09:08AM -0700 https://unacademy.com/lesson/abstract-classes/HCNAUQHC |
Juha Nieminen <nospam@thanks.invalid>: May 23 06:24AM Why doesn't the last line compile? //------------------------------------------------------------ struct Test1 {}; struct Test2 { constexpr Test2() {} }; struct Container { struct Test3 {}; struct Test4 { constexpr Test4() {} }; static constexpr Test1 object1; // Compiles static constexpr Test2 object2; // Compiles static constexpr Test3 object3; // Compiles static constexpr Test4 object4; // Does not compile }; //------------------------------------------------------------ |
Ian Collins <ian-news@hotmail.com>: May 23 07:27PM +1200 On 23/05/18 18:24, Juha Nieminen wrote: > static constexpr Test4 object4; // Does not compile > }; > //------------------------------------------------------------ Compilers are trying to tell us something: $ clang++ -std=c++17 /tmp/tt.cc /tmp/tt.cc:13:28: error: constexpr variable 'object4' must be initialized by a constant expression static constexpr Test4 object4; // Does not compile ^~~~~~~ /tmp/tt.cc:13:28: note: undefined constructor 'Test4' cannot be used in a constant expression /tmp/tt.cc:8:30: note: declared here struct Test4 { constexpr Test4() {} }; ^ 1 error generated. $ g++ -std=c++17 /tmp/tt.cc /tmp/tt.cc:10:28: error: constexpr static data member 'object1' must have an initializer static constexpr Test1 object1; // Compiles ^~~~~~~ /tmp/tt.cc:11:28: error: constexpr static data member 'object2' must have an initializer static constexpr Test2 object2; // Compiles ^~~~~~~ /tmp/tt.cc:12:28: error: constexpr static data member 'object3' must have an initializer static constexpr Test3 object3; // Compiles ^~~~~~~ /tmp/tt.cc:13:28: error: constexpr static data member 'object4' must have an initializer static constexpr Test4 object4; // Does not compile ^~~~~~~ Change the objects to object[1234](): $ clang++ -std=c++17 -c /tmp/tt.cc $ g++ -std=c++17 -c /tmp/tt.cc -- Ian. |
Paavo Helde <myfirstname@osa.pri.ee>: May 23 12:07PM +0300 On 23.05.2018 10:27, Ian Collins wrote: > static constexpr Test4 object4; // Does not compile > ^~~~~~~ > Change the objects to object[1234](): This will just declare a bunch of functions, which is probably not what OP had in mind. One ought to use object[1234]{}, but this doesn't compile for Test4 either: >g++ main.cpp main.cpp:15:33: error: 'constexpr Container::Test4::Test4()' called in a constant expression before its definition is complete static constexpr Test4 object4{}; // Does not compile ^ |
Ian Collins <ian-news@hotmail.com>: May 23 10:08PM +1200 On 23/05/18 21:07, Paavo Helde wrote: >>> static constexpr Test4 object4; // Does not compile >>> }; >>> //------------------------------------------------------------ <snip> > This will just declare a bunch of functions, which is probably not what > OP had in mind. One ought to use object[1234]{}, but this doesn't > compile for Test4 either: That was what I meant to type... > constant expression before its definition is complete > static constexpr Test4 object4{}; // Does not compile > ^ I wonder if it is to do with where inline member function definitions are parsed? The nested class is within the scope of Container, so where is a local class constructor complete? -- Ian. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 23 12:54PM +0200 On 23.05.2018 08:24, Juha Nieminen wrote: > static constexpr Test4 object4; // Does not compile > }; > //------------------------------------------------------------ It's clearly a bug, but the question is whether it's in the compilers or in the standard. I'd guess that the compilers somehow incorrectly regard `Test4` as incomplete because the containing class `Container` is incomplete. As a workaround it "should" work to just provide the explicit initialization that the error messages quoted else-thread, refer to. Cheers!, - Alf |
Sam <sam@email-scan.com>: May 23 08:30AM -0400 Juha Nieminen writes: > static constexpr Test3 object3; // Compiles > static constexpr Test4 object4; // Does not compile > }; The definition of the "Container" class is not complete until its closing brace. A constexpr object must refer to a complete class, amongst all the other requirements. "Test4" refers to a member of an incomplete class, at the time it's used. You just can't have a `constexpr` class member instance of the class itself, or of any inner classes. |
Ben Bacarisse <ben.usenet@bsb.me.uk>: May 23 02:54PM +0100 I'm piggy-backing as much as replying... >> static constexpr Test3 object3; // Compiles >> static constexpr Test4 object4; // Does not compile >> }; A data point... gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 complains about all four lines with "constexpr static data member 'object1' must have an initializer". Adding = {} to each makes it complain only about the last one with 'constexpr Container::Test4::Test4()' called in a constant expression before its definition is complete". > A constexpr object must refer to a complete class, amongst all the > other requirements. "Test4" refers to a member of an incomplete class, > at the time it's used. That's the bit that confuses me. Container is not complete, but Test4 looks complete. Adding struct Test5 { int i; }; ... static constexpr Test5 object5 = {}; provokes no complaint (for gcc or clang) and Test5 looks just as complete or incomplete as Test4. The issue must be specific to classes with constructors and I confess to not have read what C++ says about a class being complete. > You just can't have a `constexpr` class member instance of the class > itself, or of any inner classes. gcc and clang both permit such a thing in the case of Test5, so is that a compiler bug? -- Ben. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 23 02:56PM +0200 The notation is still ugly, but I got an insight: that one may need to remove/cancel an option from a base class. Then for expressing an options set "+" and "-" work better than "|". The notation is still ugly though, involving verbose "using" statements to avoid even worse verbosity: Main_window() : Top_level_window{ L"The new main window" } { using Ed = winapi::gui::Edit_control; using Opt = Ed::Options; using Ft = name::Features; using cppx::options_shortname::_; const ptr_<Ed> edit = make_new<Ed>( *this, Opt{} + _<Ft>( Ed::multiline ) ); MoveWindow( *edit, 10, 10, 640, 400, false ); } Here the "name::Features" (a pointer type in a namespace) is the way to express a name for a value, so that one can have, say, various integer values that denote different things. A less verbose alternative could perhaps be to require a separate type, maybe a boxing type, for each rôle of type's values? Ideas? Cheers!, - Alf |
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