Wednesday, October 11, 2017

Digest for comp.lang.c++@googlegroups.com - 25 updates in 5 topics

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: