- A "better" C++ - 1 Update
- TByteDynArray - 5 Updates
- Big problem with templates - 2 Updates
- std::condition_variable::wait_for - 10 Updates
- Machine code!!! \o/ - 2 Updates
- Threading Review/Feedback - 2 Updates
- Initialization of static member variables in classes. - 1 Update
- Pointer use after delete - 1 Update
- Initialization of static member variables in classes. - 1 Update
SG <s.gesemann@gmail.com>: Sep 02 04:46AM -0700 On Wednesday, August 26, 2015 at 1:05:45 PM UTC+2, jacobnavia wrote: > > https://code.google.com/p/ccl/ > > Have fun! > Interesting that none of the C++ heads objects to this :-) It's not like absence of criticism equals approval. FWIW, I looked at it (years ago?) when you announced this in comp.lang.c (or some place else). And I don't remember anyone cheering over it. At least I was left unimpressed by it. Sure, it's probably among the best thigs you could implement in plain C. But why accept the limitations of C and work around them when you can have C++? I'm not particularly in love with C++ either. It has many annoying warts. But for me it's still better than C simply because I can pick and choose the tools from a larger toolset. When I want templates I want templates and no macros or a script invoked by make to generate a piece of C code from some custom template file format by text substitution. Right now, I'm quite fond of the Rust programming language, actually. Cheers! sg |
Gerhard Wolf <leawolf@gmx.de>: Sep 02 09:46AM +0200 Hi, if have a unexpected result with the C++Builders TByteDynArray class. Pruefung[STOP] = AB; seems to pass ABs value by reference because [1]-value of Pruefung[STOP] switches to 1 after AB[1] = 1; The std::string example works as expected. Why that? How can i avoid this? Is this a C++ feature defined in the TByteDynArray class? ----the console output---------------------------------------------- 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000000000 ----the code-------------------------------------------------------- #include <vcl.h> #include <windows.h> #pragma hdrstop #pragma argsused #include <map> #include <sstream> #include <tchar.h> #include <iostream> #include <iomanip> const int STOP = 9998; std::string printTByteDynArry(TByteDynArray &td) { std::stringstream ss; for (int i(0); i < td.get_length(); i++) { ss << std::setfill('0') << std::setw(2) << i << " "; } ss << std::endl; for (int i(0); i < td.get_length(); i++) { ss << std::setfill('0') << std::setw(2) << std::hex << (unsigned int) td[i] << " "; } ss << std::endl; return ss.str(); } int _tmain(int argc, _TCHAR* argv[]) { typedef std::map<int, TByteDynArray>TBDyArrMap; TBDyArrMap Pruefung; TByteDynArray AB; AB.set_length(16); for (int i(0); i < 15; i++) AB[i] = 0; Pruefung[STOP] = AB; std::cout << printTByteDynArry(Pruefung[STOP]) << std::endl; AB[1] = 1; std::cout << printTByteDynArry(Pruefung[STOP]) << std::endl; typedef std::map<int, std::string> StrMAP; StrMAP test; std::string tmp = "0000000000"; test[1] = tmp; tmp = "1111111111"; std::cout << test[1] << std::endl; return 0; } |
Barry Schwarz <schwarzb@dqel.com>: Sep 02 02:39AM -0700 On Wed, 2 Sep 2015 09:46:44 +0200, Gerhard Wolf <leawolf@gmx.de> wrote: >seems to pass ABs value by reference because >[1]-value of Pruefung[STOP] switches to 1 after >AB[1] = 1; What is the actual type that TBytDynArray is an alias for? If https://gist.github.com/daeltar/90951 is correct, it is a class with one int member and one int* member. Since the = operator is not overloaded, assigning one such object to another should result in the corresponding members of both objects having the same value. If two pointers point to the same memory, changes made by dereferencing one pointer will show up when dereferencing the other. -- Remove del for email |
Kalle Olavi Niemitalo <kon@iki.fi>: Sep 02 01:01PM +0300 > seems to pass ABs value by reference because > [1]-value of Pruefung[STOP] switches to 1 after > AB[1] = 1; I am not familiar with C++Builder but I looked at its documentation: http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Types_TByteDynArray.html says it's defined in Delphi as "TByteDynArray = array of Byte;". That's a Delphi dynamic array type, I think. http://docwiki.embarcadero.com/Libraries/XE8/en/System.DynamicArray says the DynamicArray template in C++Builder corresponds to the Delphi dynamic array type, and it is reference counted. I suppose C++Builder then defines TByteDynArray as a typedef for DynamicArray<Byte>; I didn't find that explicitly in the documentation, but perhaps the typedef is in some header file distributed with C++Builder. > How can i avoid this? There is apparently a Copy method. http://docwiki.embarcadero.com/Libraries/XE8/en/System.DynamicArray#Assigning.2C_comparing_and_copying_dynamic_arrays |
Kalle Olavi Niemitalo <kon@iki.fi>: Sep 02 01:14PM +0300 > What is the actual type that TBytDynArray is an alias for? System::DynamicArray in C++Builder is the same size as a pointer. http://docwiki.embarcadero.com/RADStudio/XE8/en/64-bit_Windows_Data_Types_Compared_to_32-bit_Windows_Data_Types > If https://gist.github.com/daeltar/90951 is correct, it is a > class with one int member and one int* member. It is not correct: it does not define a copy assignment operator, DynamicArray::resize reads past the end of the old array when resizing to a larger size, and the comparison operators can return without specifying a value. |
Gerhard Wolf <leawolf@gmx.de>: Sep 02 12:46PM +0200 > There is apparently a Copy method. > http://docwiki.embarcadero.com/Libraries/XE8/en/System.DynamicArray#Assigning.2C_comparing_and_copying_dynamic_arrays Great! It works, thanks! |
Juha Nieminen <nospam@thanks.invalid>: Sep 02 08:11AM > This shows the education of Mr Nieminen and his attitude towards people > that do not have the same programming language tastes. > I do not call people names, Mr Nieminen, it is just bad taste. No, you only make patronizing and provocative comments with a smug attitude. Because that's so much more civilized. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
SG <s.gesemann@gmail.com>: Sep 02 03:44AM -0700 On Thursday, August 27, 2015 at 11:31:20 PM UTC+2, jacobnavia wrote: > How can I revert to the good old times? > The compiler that compiled this is gcc-4.4.3, and still does. > The new compiler however will not do that even if I specify -std=c++98 C++ compilers always have been required to do a proper "two phase lookup" (at least since its ISO standardization). It just took a while for C++ compilers to catch up. I'm not sure what the current status with Microsoft's compiler is. It may still be "too lazy" to do a two phase lookup and accept a lot of invalid C++ code. If you're interested in turning your code into valid C++ so it will be accepted by a conforming compiler, please look into how "two phase lookup" works. You may have to use the keywords "typename" or "template" or use an explicit "this->" prefix for member access here and there. Two phase lookup is not all bad. Its purpose is to catch some errors early before templates are even instantiated. But to be honest, I find it embarrassing that we have to use additional template and typename keywords for disambiguation, for example. If you're looking for a book suggestion: I found "C++ Templates: The Complete Guide" very illuminating. Cheers! sg |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 02 12:35AM +0100 On Tue, 01 Sep 2015 18:00:31 -0500 > On 9/1/2015 5:34 PM, Chris Vine wrote: > > On Tue, 01 Sep 2015 14:56:39 -0500 > > Christopher Pisz <nospam@notanaddress.com> wrote: [snip] > > you don't want a timeout, use plain std::condition_variable::wait(). > That's not the behavior I am seeing. It outputs "tick..." every 10 > seconds, as expected. Then you are outputting the ticks within the while loop. Fine if it is for debugging purposes, but otherwise at variance with the purpose of a condition variable. (Your code snippet above contained no code which printed anything - it just spun on a timeout without any purpose. More generally, looping on a timeout is also usually pointless, particularly if the condition is one to end the thread rather than to do some work. If the condition was one about the availability of work it would make a bit more sense.) > I want to loop, because the loop is where the task for the thread is > done. Unless you are implying that the work goes in the lamda..are > you? If you are doing work in the while loop above then it must surely be wrong to have gratuitous waits on a condition variable related to something completely different, namely whether a stop flag is set? > > On your mutex point, you always call > > std::condition_variable::wait{for|until}() with the mutex locked. > Isn't that what I am doing? Yes. I wasn't arguing that your code is wrong on this point, but you asked a question and I answered it. I think you may be conflating this series of posts with your one containing a request for a code review, which I haven't read. [snip] > Only when the broadcast is done? That would be ok, because all they > are going to do is go and exit. As long as the body of the while loop > can be executed in more than one thread at a time. You have lost me on while loops (the while loop above which is dependent on a timeout occurring and does nothing is only executed one thread at a time because it executes under the mutex, but I rather think you are talking about something else). I was just explaining how condition variables work, as I sensed from your question about mutexes that you weren't clear. Possibly at some point in whatever while loop you have you need to release the mutex, and acquire it again before looping. Chris |
Christopher Pisz <nospam@notanaddress.com>: Sep 01 06:57PM -0500 On 9/1/2015 6:35 PM, Chris Vine wrote: > If you are doing work in the while loop above then it must surely be > wrong to have gratuitous waits on a condition variable related to > something completely different, namely whether a stop flag is set? What's the alternative? > weren't clear. Possibly at some point in whatever while loop you have > you need to release the mutex, and acquire it again before looping. > Chris Ok, let's move this discussion to the post with the full listing and discuss the full listing. I just wanted to get past the syntax error for the one line in this OP. Once over there, Can you please write an example there with the following requirements in standard C++? 1) Create a main thread 2) Have the main thread create a number of child threads with tasks encapsulated in an object 3) Have the main thread wait on all children to exit before it, itself exits. 4) Have all children continue to do their tasks every 10 seconds, in a loop forever, until told to stop from the main thread 5) Have the main thread handle ctrl-c and tell all children to stop in response. I have no idea how to edit my code given your responses. I am just further confused. -- I have chosen to troll filter/ignore all subthreads containing the words: "Rick C. Hodgins", "Flibble", and "Islam" So, I won't be able to see or respond to any such messages --- |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 02 01:37AM +0100 On Tue, 01 Sep 2015 18:57:01 -0500 > in response. > I have no idea how to edit my code given your responses. I am just > further confused. Your "Have all children continue to do their tasks every 10 seconds" seems completely mad. Why on earth have worker threads gratuitously doing nothing for 10 seconds on every iteration between tasks, irrespective of whether there is work available. You must surely mean something else? If that really is what you want then maybe your design might be OK (subject to my point about mutex locking), but as I say it is so outside anything I could contemplate as a reasonable design aim that I couldn't say more. It is sufficiently bizarre that you ought to have explained this in your request for a code review. If this is some kind of automated machinery controller that does something (maybe polls machinery) every 10 seconds I doubt you would need threads at all: the fact that each thread must sleep for 10 seconds for this to work shows that a single thread would be more than sufficient and threads are the wrong solution. Threads are supposed to do things, not not do things. Chris |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 02 01:55AM +0100 On Wed, 2 Sep 2015 01:37:01 +0100 Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote: [snip] > seconds for this to work shows that a single thread would be more than > sufficient and threads are the wrong solution. Threads are supposed > to do things, not not do things. I would suggest a standard single-threaded program event loop with a timer for each piece of machinery. That bit of the code would require about 5 lines of code, including handling program termination. Chris |
"Christopher J. Pisz" <cpisz@austin.rr.com>: Sep 01 09:15PM -0500 On 9/1/2015 7:55 PM, Chris Vine wrote: > timer for each piece of machinery. That bit of the code would require > about 5 lines of code, including handling program termination. > Chris I want separate threads so that each will run completely independent of the other. Often when polling there is some situation where one has a failure and must retry continuously. On a single thread, that will hold up all the others. Also, processing of the data can take more than the wait time seconds, especially since it is coming over unreliable, third party http, so again, I want each to run independently. I've got a single threaded solution already. I aim to take 90% of it and plop it on a thread of its own, rather than running multiple clients. I don't see how that is uncommon at all. I've seen the same pattern at least thirty times in my career, just not with C++11. |
"Christopher J. Pisz" <cpisz@austin.rr.com>: Sep 01 09:19PM -0500 On 9/1/2015 9:15 PM, Christopher J. Pisz wrote: > plop it on a thread of its own, rather than running multiple clients. > I don't see how that is uncommon at all. I've seen the same pattern at > least thirty times in my career, just not with C++11. Oh, I should mention, I am not polling machinery, or bunches of them. Something like 10-20 data sources per client. |
"Christopher J. Pisz" <cpisz@austin.rr.com>: Sep 02 01:21AM -0500 On 9/1/2015 7:55 PM, Chris Vine wrote: > timer for each piece of machinery. That bit of the code would require > about 5 lines of code, including handling program termination. > Chris I do wonder though reading through the condition_variable docs, it mentions spinning while waiting. If it actually consumes cycles while doing nothing, it would be better not to, but I don't see any alternatives in the standard. I'd have to resort to Windows threads. There is no event or other semaphore available, is there? |
Ian Collins <ian-news@hotmail.com>: Sep 02 09:40PM +1200 Christopher J. Pisz wrote: > mentions spinning while waiting. If it actually consumes cycles while > doing nothing, it would be better not to, but I don't see any > alternatives in the standard. I'd have to resort to Windows threads. Where does it say that? A thread waiting on a CV blocks until the CV is signaled, or something else wakes it (a spurious wake-up). This could consume cycles, but it would be a poor implementation if it did. -- Ian Collins |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 02 11:20AM +0100 On Tue, 01 Sep 2015 21:15:24 -0500 "Christopher J. Pisz" <cpisz@austin.rr.com> wrote: [snip] > clients. > I don't see how that is uncommon at all. I've seen the same pattern > at least thirty times in my career, just not with C++11. OK, if that's your problem area and you are happy with your approach of a thread per device (and there are not so many devices that you are going to run into resource problems), so be it. However, although I haven't looked at the posting which contained your code other than very cursorily, it looks like you need to deal with the locking, assuming all threads share the m_stopCV and m_stopMutex objects, because at present only one thread will run its task at a time. But that is easily resolved. Your polling will not run at exactly 10 second intervals. It will be 10 seconds plus the time to run the task. If you want the time to run the task discarded, you would need to use condition_variable::wait_until() with a separate time_point object for the thread, which you reset by a further 10 seconds at each firing. Chris |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 02 11:19AM +0100 On Wed, 02 Sep 2015 01:21:36 -0500 > doing nothing, it would be better not to, but I don't see any > alternatives in the standard. I'd have to resort to Windows threads. > There is no event or other semaphore available, is there? Condition waits don't spin, unless possibly speculatively for a few nanoseconds, so you don't have a problem on that score: they don't use up clock cycles. Chris |
Gareth Owen <gwowen@gmail.com>: Sep 02 06:53AM +0100 > As Adam never existed Adam's descendants as described in > the Bible also never existed ergo Jesus Christ never existed. Formal logic is not really a strength of yours is it? |
Marcel Mueller <news.5.maazl@spamgourmet.org>: Sep 02 09:17AM +0200 On 01.09.15 23.40, Mr Flibble wrote: > extern const unsigned char main[] = { 0xEB, 0xFE }; // Machine code!!! \o/ Yippee, an infinite loop. Won't work on anything but x86 and won't work for many compilers since there is no guarantee that variable symbols will ever match function symbols. The entry point is sometimes named _main internally (or something else) and so it won't link. So what should be the use of a hack like this? Marcel |
Gerhard Wolf <leawolf@gmx.de>: Sep 02 07:29AM +0200 Am 01.09.2015 um 22:07 schrieb Christopher Pisz: > I've created a new minimal compilable example of what I want to achieve > in production code. at last Logger class header is missing. |
"Christopher J. Pisz" <cpisz@austin.rr.com>: Sep 02 01:17AM -0500 On 9/2/2015 12:29 AM, Gerhard Wolf wrote: >> I've created a new minimal compilable example of what I want to achieve >> in production code. > at last Logger class header is missing. There was a comment in the first appearance of logger.h that says, just replace it with any old threadsafe output mechanism. I don't want to include all that irrelevant code, it would just be distracting. |
ram@zedat.fu-berlin.de (Stefan Ram): Sep 02 01:08AM >>member variable is static and non-constant? >I think the issue is that for non-const static members, the compiler >needs to know where to place the memory definition (what object module This can be read in 9.4.2. As I understand it, one must define the static data member with »::« as follows: struct C { static /**/ int n /**/; }; int C::n; /* untested */ . When the first »/**/« is »const«, then we are allowed to add an initializer at the second »/**/« for some kinds of types. But we are allowed to omit the definition with »::« only if the member is not odr-used. Nobody wants to learn what »odr-used« means, so everybody must always include the ::-definition! |
Richard Damon <Richard@Damon-Family.org>: Sep 01 08:48PM -0400 On 9/1/15 9:54 AM, Chris Vine wrote: > causes a system-generated runtime fault.]" > Thanks to him for pointing that out. > Chris Interesting, this is the first place that I know of where 'implementation defined' specifically includes 'runtime fault' (presumably allowing immediate termination without any stack unwinding or cleanup). This sort of behavior is normally only the domain of undefined behavior. |
Richard Damon <Richard@Damon-Family.org>: Sep 01 08:44PM -0400 On 9/1/15 5:24 AM, Paul wrote: > static int x = 3; > // > }; I think the issue is that for non-const static members, the compiler needs to know where to place the memory definition (what object module contains the definition). For static const, this isn't an issue, as the compiler doesn't actually need to create a memory object, it can just always use the constant. For non-static members, it just knows to add the initialization to all constructors. Due to templates and inline functions, the compiler needs to have mechanisms to handle this sort of stuff, but maybe this case predates those requirements and was never added. |
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