- {} initialization inconsistency - 4 Updates
- In what scenarios can std::set::erase(const key_type& key); crash a process? - 17 Updates
- Copy construction of stateful allocators - 1 Update
- Split up vector for concurrent processing - 2 Updates
- A teaching that's worth hearing - 1 Update
| porparek@gmail.com: Oct 11 09:17AM -0700 Hi All, My g++ version 7.2.0 shows the following messages while compiling the code snippets: int b = {2.5}; error: narrowing conversion of '2.5e+0' from 'double' to 'int' inside { } [-Wnarrowing] double f = 2.5; int b = {f}; warning: narrowing conversion of 'f' from 'double' to 'int' inside { } [-Wnarrowing] Why the g++'s output is inconsistent. I do not pass any extra parameters to g++ in both cases. Of course in the second case g++ generates a binary. Thanks for clarification |
| Marcel Mueller <news.5.maazl@spamgourmet.org>: Oct 11 06:27PM +0200 > warning: narrowing conversion of 'f' from 'double' to 'int' inside { } [-Wnarrowing] > Why the g++'s output is inconsistent. I do not pass any extra parameters to g++ in both cases. > Of course in the second case g++ generates a binary. In the first case it is sure that the value 2.5 will never be assigned while in the second case the value of f might be changed meanwhile to a whole number or the truncation might be intended. I f were a compile time constant you would probably end up with the error too. Marcel |
| "James R. Kuyper" <jameskuyper@verizon.net>: Oct 11 12:34PM -0400 > warning: narrowing conversion of 'f' from 'double' to 'int' inside { } [-Wnarrowing] > Why the g++'s output is inconsistent. I do not pass any extra parameters to g++ in both cases. > Of course in the second case g++ generates a binary. When you use the numeric literal, g++ knows that 2.5 will be converted to 2.0, losing information, so it treats it as an error. When you use the variable, g++ doesn't necessarily know which value that variable will have at the time of the conversion. If it had, for instance, the value 3.0, the narrowing conversion wouldn't be a problem. Since it can't be sure, it only provides a warning. Note: if there's only one value the variable could hold at that point in the program, it might be perfectly safe, or it might be dangerous, and g++ could, in principle, use that information to decide whether an error message is needed. However, g++ is not required to figure out what value the variable must hold, and might not bother attempting to do so. |
| "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Oct 11 08:20PM +0200 On 10/11/2017 6:34 PM, James R. Kuyper wrote: > g++ could, in principle, use that information to decide whether an error > message is needed. However, g++ is not required to figure out what value > the variable must hold, and might not bother attempting to do so. A potentially narrowing conversion isn't allowed for curly braces initialization. As a practical matter the `warning` is therefore incorrect for standard-conforming mode. However, the C++ standard itself doesn't differentiate between different kinds of diagnostics such as "warning" versus "error": that's a strong in-practice convention, but not a formal requirement. At one time this was discussed at length, how the compiler could choose to treat an unnoticeably short blinking of the Caps Lock indicator as a diagnostic, use that to diagnose ANY code as a language extension, and proceed to produce an arbitrary executable, being formally correct. Which exemplifies that the C++ standard is much more a practical guide for compiler vendors than a formal description of the language. Cheers! - Alf |
| Ben Bacarisse <ben.usenet@bsb.me.uk>: Oct 11 01:44AM +0100 > In what scenarios could std::set::erase( const key_type & key) crash a > process? The obvious one is where the compare function goes wrong in some catastrophic way. But much more common would be a bug somewhere else but the code only falls over when the erase function gets called. Can you at least give the error message? It might help to know what sort of "crash" you mean. <snip> > I've also checked comparators in the value type used for the set and > they are correct, as well as simple. Both operator < and operator == > are defined correctly. OK, but you need more. You need to be sure either that they work even when the objects being compared are invalid, or you need to be sure that the objects can never become invalid. > My set is accessed in multiple threads, but there is indeed a > lock_guard at the top of the Add and at the top of the Remove methods. > The docs state that erase will not throw. Yet, here I am. A "crash" (you are not exactly clear what that means to you) is not a throw. (Technically, the docs say that your form of erase can throw an exception, but only from the compare object.) > Anyone have any ideas on what else one could look for? Can you run the code under valgrind? Can you compile and run with something like gcc's -fsanitize=undefined? These are the two I used most but there are other run-time checking systems that might be available to you. <snip> -- Ben. |
| Christopher Pisz <christopherpisz@gmail.com>: Oct 10 08:38PM -0700 On Tuesday, October 10, 2017 at 7:45:12 PM UTC-5, Ben Bacarisse wrote: > OK, but you need more. You need to be sure either that they work even > when the objects being compared are invalid, or you need to be sure that > the objects can never become invalid. Not sure what you mean here. What do you mean by invalid? the value_type is just a struct with 3 std::strings and an int. I don't see how they could become invalid. I am not dealing with pointers of any kind either. > A "crash" (you are not exactly clear what that means to you) is not a > throw. (Technically, the docs say that your form of erase can throw an > exception, but only from the compare object.) Sure. I suspect it is an access violation. I don't know how to get windows crash dump to tell me. All I can get is where the execution pointer was at the time. It is pointing to std::set::erase. Further up is a couple iterator methods and a deletor of some sort. > something like gcc's -fsanitize=undefined? These are the two I used > most but there are other run-time checking systems that might be > available to you. Windows code and windows machines. Company also doesn't have any profiling tools of course. I can run the code with warnings on and get 1000s of hits, because I just building an interface plugged into the middle of existing crappy code. If I can indeed see the same call stack in 50 some odd crash dumps from 50 different machines, without it actually being that code, but because of UDB elsewhere, then at least I can stop looking at the code being pointed to. |
| Ian Collins <ian-news@hotmail.com>: Oct 11 04:53PM +1300 On 10/11/17 04:38 PM, Christopher Pisz wrote: > value_type is just a struct with 3 std::strings and an int. I don't > see how they could become invalid. I am not dealing with pointers of > any kind either. Please wrap! Strings can have invalid pointers in them, unlikely but possible. > windows crash dump to tell me. All I can get is where the execution > pointer was at the time. It is pointing to std::set::erase. Further > up is a couple iterator methods and a deletor of some sort. Ah, so maybe something in the object you are erasing is corrupt or is being deleted twice? -- Ian |
| Melzzzzz <Melzzzzz@zzzzz.com>: Oct 11 04:58AM >> up is a couple iterator methods and a deletor of some sort. > Ah, so maybe something in the object you are erasing is corrupt or is > being deleted twice? Tree is probably corrupt by the time erase is called. -- press any key to continue or any other to quit... |
| Juha Nieminen <nospam@thanks.invalid>: Oct 11 07:03AM > In what scenarios could std::set::erase( const key_type & key) crash a process? There's a million possible reasons. Many of them not related to that code at all (for instance, something somewhere else, perhaps completely unrelated to that code, may be writing something out-of-bounds, and it happened at that instance to garbage the memory used by the std::set object.) |
| asetofsymbols@gmail.com: Oct 11 01:29AM -0700 I don't know how they have success in that, but in Axiom I did not find a stopping bug (something unresolved) until now even without a debugger and a memory analizator... Only using output[] one function as printf print variables on the screen. In C++ to find bugs is funny good and better than programming (imo) because each single bit of function for library was written by me (so I would to know how system has to run); but I have to use the debugger for find them. In C all bugs are all out library functions but i have to use debugger for to find them too. |
| asetofsymbols@gmail.com: Oct 11 01:41AM -0700 Should be one error erase one void set |
| Ralf Fassel <ralfixx@gmx.de>: Oct 11 10:46AM +0200 * Juha Nieminen <nospam@thanks.invalid> | Christopher Pisz <christopherpisz@gmail.com> wrote: | > In what scenarios could std::set::erase( const key_type & key) crash a process? | There's a million possible reasons. Many of them not related to that code at all | (for instance, something somewhere else, perhaps completely unrelated to that | code, may be writing something out-of-bounds, and it happened at that instance | to garbage the memory used by the std::set object.) Sounds much like memory corruption elsewhere. In that case it might help to enable (or not disable) the "Microsoft Safe Iterators" or whatever they are called in recent releases of Visual Studio. The related Visual Studio compiler switches are /D_ITERATOR_DEBUG_LEVEL https://msdn.microsoft.com/en-us/en-en/library/hh697468.aspx /GS (Buffer Security Check) https://msdn.microsoft.com/en-us/library/8dbf701c.aspx HTH R' |
| asetofsymbols@gmail.com: Oct 11 01:47AM -0700 I wrote Should be one error erase one void set ------ Cancel the above post, it is wrong |
| asetofsymbols@gmail.com: Oct 11 02:05AM -0700 I wrote: In C all bugs are all out library functions but i have to use debugger for to find them too. ---- Above is wrong, the problems are seg fault in the library... Yes would be better seg fault never be in library but When use memory as addresses can happen a seg fault in all the places There is a workaround use in library all heap memory first of use some range memory use a function that say that range is ok for use Or use a pure objects language without use address |
| "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Oct 11 11:16AM +0200 On 10/11/2017 1:25 AM, Christopher Pisz wrote: > In what scenarios could std::set::erase( const key_type & key) crash a process? > I received a crash dump pointing to a block of code where erase is called on a set and the process crashed. I and several of my peers cannot find a thing wrong with the code. > I think we are all familiar with the scenario where if you iterate through a container and call erase using the iterator without updating it with the result, that you have invalidated an iterator. However, I am not calling erase with an iterator, but with a key; Reproduce the issue in a minimal example. There's a very high change that the problem is your iteration-with-removal. Why don't you /beep/ post that code. Cheers!, - Alf |
| Ben Bacarisse <ben.usenet@bsb.me.uk>: Oct 11 10:39AM +0100 > value_type is just a struct with 3 std::strings and an int. I don't > see how they could become invalid. I am not dealing with pointers of > any kind either. I think we're on the same page. You are right that a struct like that won't become invalid (I had to use a vague term) in normal use, but something somewhere else might be scribbling over memory it should not touch. That causes an error somewhere else to show up in erase. <snip> >> most but there are other run-time checking systems that might be >> available to you. > Windows code and windows machines. There must be similar tools for Windows but since I don't use Windows I'm in the dark. <snip> > from 50 different machines, without it actually being that code, but > because of UDB elsewhere, then at least I can stop looking at the code > being pointed to. Not sure what you are saying here. At the moment, I think you have cast the net very wide. -- Ben. |
| scott@slp53.sl.home (Scott Lurndal): Oct 11 12:24PM >ase with an iterator, but with a key; >I've tested calling erase on the same key multiple times and it seems just = >fine. Just a guess, but I suspect something _else_ in the program is corrupting the storage used by the std::set. |
| Christopher Pisz <christopherpisz@gmail.com>: Oct 11 05:46AM -0700 On Wednesday, October 11, 2017 at 4:17:16 AM UTC-5, Alf P. Steinbach wrote: > iteration-with-removal. Why don't you /beep/ post that code. > Cheers!, > - Alf I have made several attempts at that and no use of that code in any unit test fails. Not even with multiple threads. |
| "James R. Kuyper" <jameskuyper@verizon.net>: Oct 11 12:23PM -0400 On 2017-10-11 08:46, Christopher Pisz wrote: >> Cheers!, >> - Alf > I have made several attempts at that and no use of that code in any unit test fails. Not even with multiple threads. So don't use a unit test as your starting point for the "minimal example". Something in some other part of your program is triggering this problem, and none of your unit tests includes that "something". So start with your entire program. Here's a process I've used several times. It's a long, slow process, but it often helps located even weird problems like this one: Save a copy of your program as the "known failure". Don't do anything with the original. 1. Make a copy of your "known failure" code, and choose some chunk of that program to remove or replace with a simpler version. If necessary, choose the chunk randomly, but favor large chunks, and parts of the code that you suspect have nothing to do with the problem. Every part of your program that should have executed after the point where it failed is a good candidate for removal. If the symptoms don't occur inside the data input routines, consider replacing those routines with code that initializes your data structures directly. If you can't find anything more to remove, you're done: you have your "minimal example". Hopefully, it's small enough to post to the newsgroup. Since you haven't identified the actual problem yet, feel free, if necessary, to remove parts you do suspect to have something to do with the problem - you might be wrong about that, and if so, that's useful information. Make sure to remove things cleanly. If part A of the code relies upon part B having been executed, don't remove B until after you're removed A; don't remove the '{' that starts a block of code, without also removing the '}' that terminates it; etc.. 2. Test to see if you can can still reproduce the symptoms of the problem you're trying to solve with the simplified version of the code. It's not uncommon for the symptoms to change while you're following this process. That's not a problem - as long as the new symptoms are just as much of a problem as the original symptoms, you can treat this as a successful test. However, make sure that the new symptoms are not just the result of what you removed, due to not removing it cleanly. 3. If the modified code still fails, save it as your new "known failure". If not, choose a different part to remove the next time around, possibly a subset of the code you removed this time. 4. Go back to step 1. If you follow this process, you'll often find that the fact removing a given part of the code does/doesn't remove the symptoms of your problem will provide a vital clue as to what the cause of your problem is. You might very well end up not needing to present your "minimal example" to anyone else to figure out your problem. |
| Jorgen Grahn <grahn+nntp@snipabacken.se>: Oct 11 05:06PM On Wed, 2017-10-11, Juha Nieminen wrote: > completely unrelated to that code, may be writing something > out-of-bounds, and it happened at that instance to garbage the > memory used by the std::set object.) Yeah. I bet that if the OP places a (useless) s.find(key) before the s.erase(key), he'd start getting reports about crashes there instead. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
| Jorgen Grahn <grahn+nntp@snipabacken.se>: Oct 11 05:23PM On Wed, 2017-10-11, James R. Kuyper wrote: >>> Reproduce the issue in a minimal example. >>> There's a very high change that the problem is your >>> iteration-with-removal. Why don't you /beep/ post that code. ... > with the original. > 1. Make a copy of your "known failure" code, and choose some chunk of > that program to remove or replace with a simpler version. If necessary, [snip description] Nice procedure! Sounds obvious, but probably isn't -- until someone has described it. However, it sounds like the OP is in that bad place where he cannot reproduce the problem by himself at all. Perhaps he cannot run the program in a realistic scenario. (Side note/rant: one of the most damaging things you can do to a software project is to make sure developers cannot run the full system, and neglect to support debugging in the product.) /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
| bitrex <bitrex@de.lete.earthlink.net>: Oct 11 12:23PM -0400 On 10/10/2017 03:04 PM, Daniel wrote: > get (want to get!) compile errors if you attempt to construct an object that > requires a stateful allocator without providing an allocator instance. > Daniel Ok, but if my policy's specialization default constructor is deleted (or private) how do I go about actually creating the instance to provide to the container thru the abstract interface? |
| Juha Nieminen <nospam@thanks.invalid>: Oct 11 06:52AM > you need to give your compiler as much information as possible - try to > make your loops of constant size, make data aligned suitable for > vectorisation (such as with gcc's "aligned" attribute), etc. Even the latest gcc and clang are rather poor at automatic SSE vectorization. If you really want to get the most out of it, you'll need to resort to non-portable extensions, eg. the gcc SSE intrinsics. (According to my experience, optimizing a vectorizable calculation-heavy operation manually by using SSE instrinsics directly can more than double the speed of calculation compared to just allowing the compiler to do it automatically, no matter how you structure your code. Optimizing instrinsics by hand results in significantly faster code than even using openmp SIMD pragmas.) |
| David Brown <david.brown@hesbynett.no>: Oct 11 01:55PM +0200 On 11/10/17 08:52, Juha Nieminen wrote: >> make your loops of constant size, make data aligned suitable for >> vectorisation (such as with gcc's "aligned" attribute), etc. > Even the latest gcc and clang are rather poor at automatic SSE vectorization. In my testing, clang is more enthusiastic about SSE vectorisation than gcc - often leading to inefficient code for a "loop n" if "n" is small. The compilers can do some vectorisation automatically, but they certainly have their limits. The SSE engines in modern x86 chips have a great variety, and would be a tough task for a compiler to match normal C code to these instructions. Simpler constructs, such as for matrix multiplication, should probably work (if you have the right types, the right alignment, etc.). > it automatically, no matter how you structure your code. Optimizing > instrinsics by hand results in significantly faster code than even > using openmp SIMD pragmas.) You can make the code at least somewhat portable by using the declarations from "x86intrin.h". The same code should (in theory :-) ) work with gcc, clang, MSVC, and Intel's icc. |
| seeplus <gizmomaker@bigpond.com>: Oct 11 01:26AM -0700 On Wednesday, October 11, 2017 at 12:21:38 AM UTC+11, Rick C. Hodgin wrote: > Even a woman's monthly cycle is a reminder of man's > original sin in the Garden of Eden, a permanent, personal reminder > of our accountability unto God world-wide. This is an incredibly sexist putdown and the most stupidest thing that you have said so far. |
| 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