comp.lang.c++
http://groups.google.com/group/comp.lang.c++?hl=en
comp.lang.c++@googlegroups.com
Today's topics:
* Good way to write integer overflow checks? - 13 messages, 9 authors
http://groups.google.com/group/comp.lang.c++/t/1363de0ff88836cd?hl=en
* hash_map and unordered map - 3 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/t/c9f1495ba9d6d1c5?hl=en
* Returning a class instance by value and a naming question - 5 messages, 5
authors
http://groups.google.com/group/comp.lang.c++/t/914a6523b571b0a9?hl=en
* including files best practice - 4 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/t/5558ad8b3f50bf41?hl=en
==============================================================================
TOPIC: Good way to write integer overflow checks?
http://groups.google.com/group/comp.lang.c++/t/1363de0ff88836cd?hl=en
==============================================================================
== 1 of 13 ==
Date: Tues, Nov 12 2013 12:28 pm
From: Leigh Johnston
On 12/11/2013 19:13, Alf P. Steinbach wrote:
> On 12.11.2013 19:47, James Kanze wrote:
>> On Tuesday, 12 November 2013 13:15:32 UTC, Alf P. Steinbach wrote:
>>> On 12.11.2013 11:45, James Kanze wrote:
>>>>
>>>> For the moment, all of this is new,
>>>
>>> Well, two years old. ;-)
>>
>> For whom? It's been less than a year that I've been able to use
>> a limited set of C++11, and most people I know in industry
>> cannot use it yet.
>
> g++ has supported `auto` for more than two years, since version 4.4.0 in
> april 2009.
>
> visual c++ has supported `auto` for almost exactly one year now, since
> the november 2011 CTP version (version number 17.00.51025, subtract 6 to
> get the ms marketing department's notion of version).
>
> i don't know about other compilers, sorry.
>
>
> [snip]
>> when I see auto, it tells me that someone is
>> more interested in playing around with new technology than in
>> writing code that works and that other people can understand.
>
> ouch!
>
> i think that's an unproductive attitude.
>
> but then, here we're into feelings and emotional drivers, which i
> believe are much tied to environmental factors such as the perceived
> ideas of colleagues and the main kind of code produced (in particular,
> library versus app), and i can only think of purely rational, logical,
> Mr. Spock-like general arguments, already tried above :-(
If anyone else had said that you would have "plonked" them but you
realize if you also blacklist Mr Kanze you won't have anyone left to troll.
/Leigh
== 2 of 13 ==
Date: Tues, Nov 12 2013 1:03 pm
From: scott@slp53.sl.home (Scott Lurndal)
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:
>On 12.11.2013 19:47, James Kanze wrote:
>> On Tuesday, 12 November 2013 13:15:32 UTC, Alf P. Steinbach wrote:
>>> On 12.11.2013 11:45, James Kanze wrote:
>>>>
>>>> For the moment, all of this is new,
>>>
>>> Well, two years old. ;-)
>>
>> For whom? It's been less than a year that I've been able to use
>> a limited set of C++11, and most people I know in industry
>> cannot use it yet.
>
>g++ has supported `auto` for more than two years, since version 4.4.0 in
>april 2009.
Why should that matter? My current C++ project needs to compile on various
versions of GCC from 4.1.2 to 4.6.4. We certainly cannot use C++11 features
and don't expect to be able to for several years to come, if then.
C++ is perfectly usable without all the C++11 cruft which, when used for
silly reasons (your -> auto return value declarations) just makes the code
harder to read and maintain. I do like the built-in threads in C++11, but
pthreads work just fine here.
And no, we cannot upgrade to newer compilers without serious and very costly
disruption. Probably won't start using C++11 until a new project is started from
scratch that has no external binary dependencies (which seems unlikely at the
moment). I suspect this is the norm for most real-world projects with more than
a single programmer on the team and more than a single C++ project within a product.
== 3 of 13 ==
Date: Tues, Nov 12 2013 1:21 pm
From: David Brown
On 12/11/13 20:27, Alf P. Steinbach wrote:
> On 12.11.2013 20:10, Ian Collins wrote:
>>
>> Branding someone who disagrees with a troll is poor form. You are
>> possibly the only regular here (and on c.l.c) who considers David Brown
>> to be a troll.
>
> Possibly, but not likely. :-)
>
If there are any others who think I am a troll, or have been lying or
deliberately misrepresenting facts, then please let me know. (And if
anyone knows specifically what Alf is talking about, and can point to
where I have lied - or written something that could be interpreted as a
lie - then let me know of that too.)
Like most people, I make occasional factual errors. I accept
corrections, possibly after a discussion about /why/ I am in error. And
if it was a silly mistake that I could easily have checked, then I feel
silly about it - but no one else should feel insulted or angry as a
result, nor should they mistake an error for a lie.
Like most people, I disagree with a number of opinions held by others in
this group - that is neither an error nor a lie.
> Especially, what you say is unlikely given earlier comments asking why I
> continued to engage in a clearly trolling thread, when I'd already
> plinked some trolls here.
>
>
>> I can't see why.
>
> Because he doesn't just disagree, he mostly misrepresents and lies.
>
> I define "lie" as when someone actively tries to convince others of that
> which he (or she) knows is false, and I only say that in public when
> it's proved. Or at least I hope I do. Anyway, he lies.
>
> I think there should be room, here and in other groups, for all honest
> people, also those (e.g. Aspberger's) who appear to many others to be
> trolls. And I consider it worth fighting for persons who are wrongly
> excluded or made subject of ad hominem campaigns, and so I've done that
> (most recently elswhere, though). But I also think that the dishonest
> ones should be plinked, and, unlike the opinon here of the only person I
> ever killfiled on SO, that the reasons for such actions should be made
> clear. If it's lying, then IMHO it needs to be said. In clear.
>
I agree that /if/ someone is lying, it should be called out (though not
judged and condemned until the case is clear). And I agree that it
should be "in clear" - and yet I am at a loss to see what you are
referring to as my lies and deliberate misrepresentation. I can only
assume that something I wrote particularly irritated you in some way -
perhaps I was unreasonably sarcastic in a comment. In the interest of
peace in this newsgroup, and a return to technical discussions, I will
be happy to apologise if I have insulted you in some way.
So let me know /exactly/ what the problem is, and we can put this behind us.
>
> Cheers & hth.,
>
> - Alf
>
== 4 of 13 ==
Date: Tues, Nov 12 2013 1:50 pm
From: Ian Collins
David Brown wrote:
Something Alf should see...
> On 12/11/13 20:27, Alf P. Steinbach wrote:
>> On 12.11.2013 20:10, Ian Collins wrote:
>>>
>>> Branding someone who disagrees with a troll is poor form. You are
>>> possibly the only regular here (and on c.l.c) who considers David Brown
>>> to be a troll.
>>
>> Possibly, but not likely. :-)
>>
>
> If there are any others who think I am a troll, or have been lying or
> deliberately misrepresenting facts, then please let me know. (And if
> anyone knows specifically what Alf is talking about, and can point to
> where I have lied - or written something that could be interpreted as a
> lie - then let me know of that too.)
>
> Like most people, I make occasional factual errors. I accept
> corrections, possibly after a discussion about /why/ I am in error. And
> if it was a silly mistake that I could easily have checked, then I feel
> silly about it - but no one else should feel insulted or angry as a
> result, nor should they mistake an error for a lie.
>
> Like most people, I disagree with a number of opinions held by others in
> this group - that is neither an error nor a lie.
>
>> Especially, what you say is unlikely given earlier comments asking why I
>> continued to engage in a clearly trolling thread, when I'd already
>> plinked some trolls here.
>>
>>
>>> I can't see why.
>>
>> Because he doesn't just disagree, he mostly misrepresents and lies.
>>
>> I define "lie" as when someone actively tries to convince others of that
>> which he (or she) knows is false, and I only say that in public when
>> it's proved. Or at least I hope I do. Anyway, he lies.
>>
>> I think there should be room, here and in other groups, for all honest
>> people, also those (e.g. Aspberger's) who appear to many others to be
>> trolls. And I consider it worth fighting for persons who are wrongly
>> excluded or made subject of ad hominem campaigns, and so I've done that
>> (most recently elswhere, though). But I also think that the dishonest
>> ones should be plinked, and, unlike the opinon here of the only person I
>> ever killfiled on SO, that the reasons for such actions should be made
>> clear. If it's lying, then IMHO it needs to be said. In clear.
>>
>
> I agree that /if/ someone is lying, it should be called out (though not
> judged and condemned until the case is clear). And I agree that it
> should be "in clear" - and yet I am at a loss to see what you are
> referring to as my lies and deliberate misrepresentation. I can only
> assume that something I wrote particularly irritated you in some way -
> perhaps I was unreasonably sarcastic in a comment. In the interest of
> peace in this newsgroup, and a return to technical discussions, I will
> be happy to apologise if I have insulted you in some way.
>
> So let me know /exactly/ what the problem is, and we can put this behind us.
I case Alf really has plonked you, he'll see this!
--
Ian Collins
== 5 of 13 ==
Date: Tues, Nov 12 2013 1:51 pm
From: Chris Vine
On Tue, 12 Nov 2013 20:27:19 +0100
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> wrote:
> On 12.11.2013 20:10, Ian Collins wrote:
> >
> > Branding someone who disagrees with a troll is poor form. You are
> > possibly the only regular here (and on c.l.c) who considers David
> > Brown to be a troll.
>
> Possibly, but not likely. :-)
>
> Especially, what you say is unlikely given earlier comments asking
> why I continued to engage in a clearly trolling thread, when I'd
> already plinked some trolls here.
>
>
> > I can't see why.
>
> Because he doesn't just disagree, he mostly misrepresents and lies.
>
> I define "lie" as when someone actively tries to convince others of
> that which he (or she) knows is false, and I only say that in public
> when it's proved. Or at least I hope I do. Anyway, he lies.
Obviously he doesn't know it is false. At worst he is mistaken. The
fact is that you regard anyone who disagrees with you as a troll. Or
more to the point, you brand them a troll so you can justify your
ridiculous "plink". And then, to make yourself feel better about it,
you then brand them a liar.
You really need to grow up a little.
Chris
== 6 of 13 ==
Date: Tues, Nov 12 2013 2:01 pm
From: Chris Vine
On Tue, 12 Nov 2013 14:33:26 +0100
David Brown <david@westcontrol.removethisbit.com> wrote:
> On 12/11/13 13:37, Alf P. Steinbach wrote:
> > Please don't pay attention to David Brown. Whenever he says
> > something about what others mean, you can be reasonably sure that
> > it's at best misrepresentation, and at worst a complete fantasy. In
> > short, he's heavily into misrepresentation and other forms of
> > trolling.
> >
> > Regarding the C++ expression at hand, -1/2u is well-defined, casting
> > that back to integer will in practice not incur overflow, not even
> > on one complement's machines are sign and magnitude, but the holy
> > standard does admit implementations with rather more perverse value
> > ranges, simply by not considering the possibility that they could
> > exist...
> >
> > One can trust David Brown to latch on to such, and also to not
> > understand whatever he's read about it (he thought -1/2u was UB).
> >
> >
> > Cheers,
> >
> > - Alf (pretty annoyed at himself for being suckered into DB's world)
> >
>
> I don't know if you are reading this, Alf, but could you please just
> drop this attitude? It helps no one, and I am sure I am not the only
> one getting tired of it. /Nothing/ I have posted here has been
> deliberate misrepresentation, lying, or intentional or active
> "trolling".
And this guy is apparently a comp.lang.c++.moderated moderator, or so
he claims.
Chris
== 7 of 13 ==
Date: Tues, Nov 12 2013 2:14 pm
From: "Alf P. Steinbach"
On 12.11.2013 22:50, Ian Collins wrote:
>
> I case Alf really has plonked you, he'll see this!
Thanks, but as it turned out that was not necessary: he'd changed his
e-mail address[1] for this. Which was in a way considerate. Which could
almost be baffling, but it makes sense since the main thrust was just
more of the same, trying to engage me and rally others -- appearing
reasonable.
Cheers & thanks!,
- Alf
Notes:
[1] The new mail address [david.brown@removethis.hesbynett.no] is with a
Norwegian ISP. Mostly only usable for Norwegians. The one already in my
killfile, [david@westcontrol.removethisbit.com], was with a Norwegian
firm. Since I'm Norwegian I may have encountered "David Brown" or people
that he know, in real life, and possibly I could then have been less
than tactful, which could explain his animosity here.
== 8 of 13 ==
Date: Tues, Nov 12 2013 3:20 pm
From: David Brown
On 12/11/13 23:14, Alf P. Steinbach wrote:
> On 12.11.2013 22:50, Ian Collins wrote:
>>
>> I case Alf really has plonked you, he'll see this!
>
> Thanks, but as it turned out that was not necessary: he'd changed his
> e-mail address[1] for this. Which was in a way considerate. Which could
> almost be baffling, but it makes sense since the main thrust was just
> more of the same, trying to engage me and rally others -- appearing
> reasonable.
>
>
> Cheers & thanks!,
>
> - Alf
>
> Notes:
> [1] The new mail address [david.brown@removethis.hesbynett.no] is with a
> Norwegian ISP. Mostly only usable for Norwegians. The one already in my
> killfile, [david@westcontrol.removethisbit.com], was with a Norwegian
> firm. Since I'm Norwegian I may have encountered "David Brown" or people
> that he know, in real life, and possibly I could then have been less
> than tactful, which could explain his animosity here.
>
As I noted in another post (which you may have missed), I happen to have
two different epost addresses when posting from two different computers.
I don't think anyone else has noticed or bothered about it.
I am not Norwegian (I'm Scottish), but I live in Norway.
I have no animosity against you or anyone else. I have disagreed with
you regarding signed overflow behaviour - I make no apology for that,
and I stand by my opinions there. (Of course the factual errors I made
about details of the standards are another matter.) I might have been
"less than tactful" in some of my posts, but I think you'll agree that
that is not uncommon on Usenet, especially when arguments are getting
frustratingly unproductive.
== 9 of 13 ==
Date: Tues, Nov 12 2013 10:39 pm
From: Rosario1903
On Sat, 09 Nov 2013 16:28:29 +0100, "Alf P. Steinbach" wrote:
>This code is in support of some API functionality:
>[code]
>inline
>auto can_inflate( gdi::Rect const& r, int const dx, int const dy )
> -> bool
>{
> CPPX_XASSERT( INT_MIN/2 < dx && dx < INT_MAX/2 );
> CPPX_XASSERT( INT_MIN/2 < dy && dy < INT_MAX/2 );
>
> typedef unsigned long Unsigned_long;
> auto const msb = ULONG_MAX - (ULONG_MAX >> 1);
> return
> (r.left & msb) == ((Unsigned_long( r.left ) - dx) & msb) &&
> (r.top & msb) == ((Unsigned_long( r.top ) - dy) & msb) &&
....
>
>Can this be written in an even gooder way, for bestest possible code?
>Disclaimer: the code has not been tested or even called.
>Cheers,
>- Alf
it is the compiler that have to do that...
i think the easy form for a C or C++ language would be the follow:
int function(void)
{u32 a, b, r, s, cf;
a=0xFF; b=789799; r=7877;
makeCarryFlagTheLastStatement(&cf);
/* signal to the compiler cf var is the carry flag for overflow
in the last statement and initalize it to 0
*/
s=a*b+c;
if(cf==0) printf("Not carry flag the last statement\n");
else printf("There is one statement with overflow\n");
return 0;
}
where cf would detect integer overflow, unsigned overflow and float
point overflow
== 10 of 13 ==
Date: Wed, Nov 13 2013 2:45 am
From: David Brown
On 13/11/13 07:39, Rosario1903 wrote:
> On Sat, 09 Nov 2013 16:28:29 +0100, "Alf P. Steinbach" wrote:
>> This code is in support of some API functionality:
>> [code]
>> inline
>> auto can_inflate( gdi::Rect const& r, int const dx, int const dy )
>> -> bool
>> {
>> CPPX_XASSERT( INT_MIN/2 < dx && dx < INT_MAX/2 );
>> CPPX_XASSERT( INT_MIN/2 < dy && dy < INT_MAX/2 );
>>
>> typedef unsigned long Unsigned_long;
>> auto const msb = ULONG_MAX - (ULONG_MAX >> 1);
>> return
>> (r.left & msb) == ((Unsigned_long( r.left ) - dx) & msb) &&
>> (r.top & msb) == ((Unsigned_long( r.top ) - dy) & msb) &&
> ....
>>
>> Can this be written in an even gooder way, for bestest possible code?
>> Disclaimer: the code has not been tested or even called.
>> Cheers,
>> - Alf
>
> it is the compiler that have to do that...
> i think the easy form for a C or C++ language would be the follow:
>
> int function(void)
> {u32 a, b, r, s, cf;
> a=0xFF; b=789799; r=7877;
> makeCarryFlagTheLastStatement(&cf);
> /* signal to the compiler cf var is the carry flag for overflow
> in the last statement and initalize it to 0
> */
> s=a*b+c;
> if(cf==0) printf("Not carry flag the last statement\n");
> else printf("There is one statement with overflow\n");
> return 0;
> }
>
> where cf would detect integer overflow, unsigned overflow and float
> point overflow
>
As it stands, there are many reasons why code like that could not work.
It is possible on many targets to read the overflow flag from the cpu's
flag register (or "processor status register" - names vary). The
details will be dependent on the cpu in question, and also the compiler
- you would need either inline assembly code or a toolchain-specific
built-in function. However, even if you have made an inline assembly
function that reads the overflow flag, it may not give you the answer
you want.
For some cpu's (such as the PPC), flags are not updated unless the
instruction specifically asks for it - in your "s = a*b + c" a PPC
compiler would use instructions that do not change the flags.
If you write code such as :
s = a * b + c;
if (readOverflowFlag()) ...
where "readOverflowFlag()" is an inline assembly function, the compiler
will typically be free to move the assembly code around with respect to
the "s = a * b + c" calculation. You would have to force the relative
positioning by using volatiles, calls to external code, or other methods
to be sure that the calculation is done as you want, with the order you
want.
And of course you only get the overflow flag from the last operation -
so if you are doing "s = a * b + c" your overflow flag will represent a
check on the addition, but not a check on the multiplication.
One possibility if you need to check the overflow after a number of
calculations is to expand the range of your integers (such as moving to
64-bit integers here), do the calculations, then at the end check for
range overflows before converting back to the 32-bit values.
== 11 of 13 ==
Date: Wed, Nov 13 2013 7:02 am
From: Rosario1903
On Wed, 13 Nov 2013 11:45:26 +0100, David Brown wrote:
>On 13/11/13 07:39, Rosario1903 wrote:
>> On Sat, 09 Nov 2013 16:28:29 +0100, "Alf P. Steinbach" wrote:
>>> This code is in support of some API functionality:
>>> [code]
>>> inline
>>> auto can_inflate( gdi::Rect const& r, int const dx, int const dy )
>>> -> bool
>>> {
>>> CPPX_XASSERT( INT_MIN/2 < dx && dx < INT_MAX/2 );
>>> CPPX_XASSERT( INT_MIN/2 < dy && dy < INT_MAX/2 );
>>>
>>> typedef unsigned long Unsigned_long;
>>> auto const msb = ULONG_MAX - (ULONG_MAX >> 1);
>>> return
>>> (r.left & msb) == ((Unsigned_long( r.left ) - dx) & msb) &&
>>> (r.top & msb) == ((Unsigned_long( r.top ) - dy) & msb) &&
>> ....
>>>
>>> Can this be written in an even gooder way, for bestest possible code?
>>> Disclaimer: the code has not been tested or even called.
>>> Cheers,
>>> - Alf
>>
>> it is the compiler that have to do that...
>> i think the easy form for a C or C++ language would be the follow:
>>
>> int function(void)
>> {u32 a, b, r, s, cf;
>> a=0xFF; b=789799; r=7877;
>> makeCarryFlagTheLastStatement(&cf);
>> /* signal to the compiler cf var is the carry flag for overflow
>> in the last statement and initalize it to 0
>> */
>> s=a*b+c;
the above would be "s=a*b+r"
>> if(cf==0) printf("Not carry flag the last statement\n");
>> else printf("There is one statement with overflow\n");
for to be clear, in nasm x86 i mean something as:
function:
sub esp, 20
; cf=0, s=4, r=8, b=12, a=16
mov dword[esp+0], 0
mov dword[esp+8], 7877
mov dword[esp+12],789799
mov dword[esp+16],0FFh
; s=a*b+r C statement
mov ecx, 0 ; ecx carry flag
mov edx, 0
mov eax, [esp+16]
mul dword[esp+12]
cmp edx, 0
je .1
mov ecx, 1
.1: add eax, [esp+8]
adc ecx, 0
mov [esp+0], ecx
; if( cf==0 )
cmp dword[esp+0], 0
je etc
>> return 0;
add esp, 20
ret
>> }
>>
>> where cf would detect integer overflow, unsigned overflow and float
>> point overflow
>>
>
>As it stands, there are many reasons why code like that could not work.
>
>It is possible on many targets to read the overflow flag from the cpu's
>flag register (or "processor status register" - names vary).
one could do all with the instruction "adc" = "add and carry" i think
if cpu has not carry flag
>The
>details will be dependent on the cpu in question, and also the compiler
>- you would need either inline assembly code or a toolchain-specific
>built-in function. However, even if you have made an inline assembly
>function that reads the overflow flag, it may not give you the answer
>you want.
yes because each 2 operation "*" and "+" in "s=a*b+c" can write the
carry flag, so it is the compiler that has to do it
or the assembly programer...
>For some cpu's (such as the PPC), flags are not updated unless the
>instruction specifically asks for it - in your "s = a*b + c" a PPC
>compiler would use instructions that do not change the flags.
>
>If you write code such as :
>
> s = a * b + c;
> if (readOverflowFlag()) ...
>
>where "readOverflowFlag()" is an inline assembly function, the compiler
>will typically be free to move the assembly code around with respect to
>the "s = a * b + c" calculation. You would have to force the relative
>positioning by using volatiles, calls to external code, or other methods
>to be sure that the calculation is done as you want, with the order you
>want.
the order i want is the order that the compiler/standard says; there
are no UB there if standard give precedence table for operations and
the use of ()
>And of course you only get the overflow flag from the last operation -
>so if you are doing "s = a * b + c" your overflow flag will represent a
>check on the addition, but not a check on the multiplication.
>
>
>One possibility if you need to check the overflow after a number of
>calculations is to expand the range of your integers (such as moving to
>64-bit integers here), do the calculations, then at the end check for
>range overflows before converting back to the 32-bit values.
i think cpu has instructions for see if there are overflow in each
simple instruction one can find in the statement as in
a=(r*b+(c<<3) - 50.8/12.4) etc etc
and so it would easy count number of overflow for the statement in one
variable
that one define in the same function where that statement is.
this because many threads can have to use the same trick for find
overflow
== 12 of 13 ==
Date: Wed, Nov 13 2013 8:58 am
From: David Brown
On 13/11/13 16:02, Rosario1903 wrote:
> On Wed, 13 Nov 2013 11:45:26 +0100, David Brown wrote:
>> On 13/11/13 07:39, Rosario1903 wrote:
>>> On Sat, 09 Nov 2013 16:28:29 +0100, "Alf P. Steinbach" wrote:
>>>> This code is in support of some API functionality:
>>>> [code]
>>>> inline
>>>> auto can_inflate( gdi::Rect const& r, int const dx, int const dy )
>>>> -> bool
>>>> {
>>>> CPPX_XASSERT( INT_MIN/2 < dx && dx < INT_MAX/2 );
>>>> CPPX_XASSERT( INT_MIN/2 < dy && dy < INT_MAX/2 );
>>>>
>>>> typedef unsigned long Unsigned_long;
>>>> auto const msb = ULONG_MAX - (ULONG_MAX >> 1);
>>>> return
>>>> (r.left & msb) == ((Unsigned_long( r.left ) - dx) & msb) &&
>>>> (r.top & msb) == ((Unsigned_long( r.top ) - dy) & msb) &&
>>> ....
>>>>
>>>> Can this be written in an even gooder way, for bestest possible code?
>>>> Disclaimer: the code has not been tested or even called.
>>>> Cheers,
>>>> - Alf
>>>
>>> it is the compiler that have to do that...
>>> i think the easy form for a C or C++ language would be the follow:
>>>
>>> int function(void)
>>> {u32 a, b, r, s, cf;
>>> a=0xFF; b=789799; r=7877;
>>> makeCarryFlagTheLastStatement(&cf);
>>> /* signal to the compiler cf var is the carry flag for overflow
>>> in the last statement and initalize it to 0
>>> */
>>> s=a*b+c;
>
> the above would be "s=a*b+r"
>
>>> if(cf==0) printf("Not carry flag the last statement\n");
>>> else printf("There is one statement with overflow\n");
>
> for to be clear, in nasm x86 i mean something as:
>
> function:
> sub esp, 20
> ; cf=0, s=4, r=8, b=12, a=16
> mov dword[esp+0], 0
> mov dword[esp+8], 7877
> mov dword[esp+12],789799
> mov dword[esp+16],0FFh
> ; s=a*b+r C statement
> mov ecx, 0 ; ecx carry flag
> mov edx, 0
> mov eax, [esp+16]
> mul dword[esp+12]
> cmp edx, 0
> je .1
> mov ecx, 1
> .1: add eax, [esp+8]
> adc ecx, 0
> mov [esp+0], ecx
> ; if( cf==0 )
> cmp dword[esp+0], 0
> je etc
>
>
>>> return 0;
> add esp, 20
> ret
>>> }
>>>
>>> where cf would detect integer overflow, unsigned overflow and float
>>> point overflow
>>>
>>
>> As it stands, there are many reasons why code like that could not work.
>>
>> It is possible on many targets to read the overflow flag from the cpu's
>> flag register (or "processor status register" - names vary).
>
> one could do all with the instruction "adc" = "add and carry" i think
> if cpu has not carry flag
>
>> The
>> details will be dependent on the cpu in question, and also the compiler
>> - you would need either inline assembly code or a toolchain-specific
>> built-in function. However, even if you have made an inline assembly
>> function that reads the overflow flag, it may not give you the answer
>> you want.
>
> yes because each 2 operation "*" and "+" in "s=a*b+c" can write the
> carry flag, so it is the compiler that has to do it
> or the assembly programer...
>
>> For some cpu's (such as the PPC), flags are not updated unless the
>> instruction specifically asks for it - in your "s = a*b + c" a PPC
>> compiler would use instructions that do not change the flags.
>>
>> If you write code such as :
>>
>> s = a * b + c;
>> if (readOverflowFlag()) ...
>>
>> where "readOverflowFlag()" is an inline assembly function, the compiler
>> will typically be free to move the assembly code around with respect to
>> the "s = a * b + c" calculation. You would have to force the relative
>> positioning by using volatiles, calls to external code, or other methods
>> to be sure that the calculation is done as you want, with the order you
>> want.
>
> the order i want is the order that the compiler/standard says; there
> are no UB there if standard give precedence table for operations and
> the use of ()
(Others will hopefully correct me here if I'm wrong...)
The compiler has to generate code /as if/ it followed the ordering in
the source code and the precedence rules for operators. But it can
re-arrange the /actual/ generated code, as long as the effect is the
same. Since any effect on flags is not visible in C or C++ in a
calculation like "a * b + c", the compiler does not have to consider it
when arranging instructions. If the "readOverflowFlag()" is an inline
assembly function, the compiler will probably treat it like a volatile
access - and obey its ordering with respect to other volatile accesses,
to function calls that /may/ have unknown effects, code that /may/ cause
an exception, etc. But simple arithmetic using local data can usually
be moved around quite freely.
I don't think there is any sort of undefined behaviour here - it is just
that C and C++ does not consider effects on flags as "behaviour" of
arithmetic instructions.
I have seen similar things in C, especially in embedded systems, and I
assume the same can apply to C++. People write code like this:
extern volatile bool globalInterruptEnable; // CPU flag
static inline void disableInterrupts(void) {
globalInterruptEnable = false;
}
static inline void enableInterrupts(void) {
globalInterruptEnable = true;
}
static int partA, partB;
void atomicUpdate(int a, b) {
disableInterrupts();
partA = a;
partB = b;
enableInterrupts();
}
I have seen many developers think that code like this will execute the
"partA = a; partB = b;" code with interrupts disabled. The think that
either the volatile nature of the globalInterruptEnable flag, or the
function calls, force this ordering. In fact, the only ordering you are
guaranteed is that that enableInterrupts() comes after
disableInterrupts() - the setting of "parts" can be done before,
between, or after these calls.
It is therefore always dangerous to assume the compiler will generate
code that runs in a particular way or a particular order, just because
it is in that order in your source code.
>
>> And of course you only get the overflow flag from the last operation -
>> so if you are doing "s = a * b + c" your overflow flag will represent a
>> check on the addition, but not a check on the multiplication.
>>
>>
>> One possibility if you need to check the overflow after a number of
>> calculations is to expand the range of your integers (such as moving to
>> 64-bit integers here), do the calculations, then at the end check for
>> range overflows before converting back to the 32-bit values.
>
> i think cpu has instructions for see if there are overflow in each
> simple instruction one can find in the statement as in
> a=(r*b+(c<<3) - 50.8/12.4) etc etc
> and so it would easy count number of overflow for the statement in one
> variable
> that one define in the same function where that statement is.
> this because many threads can have to use the same trick for find
> overflow
>
A compiler certainly /could/ generate such code - but it would make
things bigger and slower. On super-scaler cpus, code like that would
probably cause pipeline stalls and bottlenecks, leading to very much
slower code.
Some processors have "sticky" bits for things like overflows, which are
set by any overflowing operation but are not cleared except by explicit
instructions. These make it easy to do a sequence of operations and see
if there has been an overflow along the way. I think such sticky bits
are more common for floating point operations rather than integer
operations, but obviously it will depend on the cpu in question.
== 13 of 13 ==
Date: Thurs, Nov 14 2013 8:53 am
From: David Harmon
On Mon, 11 Nov 2013 18:47:23 +0000 in comp.lang.c++, Leigh Johnston
<leigh@i42.co.uk> wrote,
>The idiot "plink'd" you which is idiot-speak for blacklisting your
>posts. He has also "plink'd" me as the guy can't handle criticism.
A man's got to know his limitations.
-- Dirty Harry
>
==============================================================================
TOPIC: hash_map and unordered map
http://groups.google.com/group/comp.lang.c++/t/c9f1495ba9d6d1c5?hl=en
==============================================================================
== 1 of 3 ==
Date: Wed, Nov 13 2013 7:05 am
From: jashan4235@gmail.com
So there was a fuzzy logic code i saw on http://www.codeproject.com/Articles/316668/Cplusplus-Fuzzy-Logic-API-plus-Simple-DSL and i was using it for simple learning of fuzzy implementation but when using it in ubuntu 12.04 gcc version 4.6.3 an instance of fuzzylogic.cpp i.e hash_map was giving error and i did some research and it came out something about unordered map but still now being a novice programmer i am not able to identify the actual problem.I atcually want to know what is the latest implementation of hash_map??
== 2 of 3 ==
Date: Wed, Nov 13 2013 9:17 am
From: Paavo Helde
jashan4235@gmail.com wrote in
news:5c7409af-cc6b-489c-8762-6ab4da754633@googlegroups.com:
>I atcually want to know what is the latest implementation of
> hash_map??
You should use std::unordered_map which comes with your C++ compiler.
Cheers
Paavo
== 3 of 3 ==
Date: Wed, Nov 13 2013 12:20 pm
From: Jorgen Grahn
On Wed, 2013-11-13, Paavo Helde wrote:
> jashan4235@gmail.com wrote in
> news:5c7409af-cc6b-489c-8762-6ab4da754633@googlegroups.com:
>
>>I atcually want to know what is the latest implementation of
>> hash_map??
>
> You should use std::unordered_map which comes with your C++ compiler.
Different answer: the latest version of hash_map is probably from the
mid-1990s when HP and SGI fiddled with it. I doubt anyone else made
any important changes to it.
People used hash_map as a faster but non-standard alternative to
std::map over the decades, until it was finally standardized in a
slightly different form called first std::tr1::unordered_map, and then
in C++11 std::unordered_map.
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
==============================================================================
TOPIC: Returning a class instance by value and a naming question
http://groups.google.com/group/comp.lang.c++/t/914a6523b571b0a9?hl=en
==============================================================================
== 1 of 5 ==
Date: Wed, Nov 13 2013 3:09 pm
From: DSF
Hello,
I have a class I've been writing where I frequently need to return
the class by value so that class members can be changed without
affecting the original. The problem is all of the copying. First,
the class has to be copied into a local instance of the class. Then,
upon return, the local instance is copied into an unnamed instance
that's created before the function is called, and therefore not
destroyed when the function ends. Finally, after the function ends,
the operator= of the target is called, yet again copying the class
(unnamed). Here is an example:
FStringW FStringW::Start(size_t end) const
{
FStringW tfs(*this);
if(end < length)
{
tfs.str[end] = 0;
tfs.length = end;
}
tfs.StartIP(end);
return tfs;
}
StartIP is a member function that alters the string in place.
It returns 'end' number of characters of the start of a wide string.
I tried creating a "global" temp that could be used in place of each
function that used 'tfs'. It was a pointer to FStringW that was
created in each constructor and deleted in the destructor. I managed
to avoid an infinite loop in the constructor, but didn't realize it
created one in the destructor, too. I wasn't able to get around that
one. All the functions that returned FStringW returned a reference to
the global object, so the reference had the lifetime of until another
function uses it. That was acceptable. It would have eliminated one
copy if it worked.
So the question is: Are there any techniques for minimizing the
number of copies that occur when returning by value?
The ideal situation would be if the returned object could become the
unnamed object that's passed to operator=. But I think the compiler
would have to do that. And there's always the chance the function
could return an expression i.e. return tfs1 + tfs2.
My second question relates to the naming of member functions. Most
string-altering functions I've written have two versions, one that
returns by value and leaves the original alone, and one that alters
the string in place. For now, I'm using:
FStringW FStringW::Start(size_t end);
void FStringW::StartIP(size_t end);
But I was thinking maybe something like:
FStringW FStringW::GetStringStart(size_t end);
void FStringW::StringStart(size_t end);
Something like Crop or Cut StringEnd is more descriptive, but uses
start and end as terms for functions that do very similar things. Any
Ideas?
Thanks.
"'Later' is the beginning of what's not to be."
D.S. Fiscus
== 2 of 5 ==
Date: Wed, Nov 13 2013 4:17 pm
From: Jorgen Grahn
On Wed, 2013-11-13, DSF wrote:
> Hello,
>
> I have a class I've been writing where I frequently need to return
> the class by value so that class members can be changed without
> affecting the original. The problem is all of the copying.
[...]
Are you saying that doing it the naive, straightforward way causes
performance problems in your application? Because otherwise I'd stop
worrying and just do it that way.
(I'm asking because I myself have an unfortunate tendency to
micro-optimise things, so perhaps others do, too.)
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
== 3 of 5 ==
Date: Wed, Nov 13 2013 4:31 pm
From: ram@zedat.fu-berlin.de (Stefan Ram)
DSF <notavalid@address.here> writes:
> I have a class I've been writing where I frequently need to return
>the class by value so that class members can be changed without
>affecting the original.
What you return is called »an instance of the class«
or »an object of the class«. It's not the class.
>upon return, the local instance is copied into an unnamed instance
Return values are rvalues, they are moved, not copied.
> So the question is: Are there any techniques for minimizing the
>number of copies that occur when returning by value?
Move members (move constructors and move assignements) are
already generated by the compiler, unless you defined one of
them or copy members or destructors.
I think, you just have to take care to mark non-obvious
rvalues with ::std::move and to have handles to resources
as members (not large members).
== 4 of 5 ==
Date: Wed, Nov 13 2013 10:49 pm
From: Paavo Helde
DSF <notavalid@address.here> wrote in
news:g9g789tnbu5lfsjal0pqg6clcpervqqmth@4ax.com:
> Hello,
>
> I have a class I've been writing where I frequently need to return
> the class by value so that class members can be changed without
> affecting the original. The problem is all of the copying.
How do you know? Have you profiled the code and seen this is a
bottleneck?
> First,
> the class has to be copied into a local instance of the class. Then,
> upon return, the local instance is copied into an unnamed instance
> that's created before the function is called, and therefore not
> destroyed when the function ends. Finally, after the function ends,
> the operator= of the target is called, yet again copying the class
> (unnamed). Here is an example:
>
> FStringW FStringW::Start(size_t end) const
> {
> FStringW tfs(*this);
> if(end < length)
> {
> tfs.str[end] = 0;
> tfs.length = end;
> }
> tfs.StartIP(end);
> return tfs;
> }
>
> StartIP is a member function that alters the string in place.
>
> It returns 'end' number of characters of the start of a wide string.
>
> I tried creating a "global" temp that could be used in place of each
> function that used 'tfs'.
Whatever you do, don't do this. Global (non-const) variables are evil,
they complicate the data flow, make the optimizations harder and will
create lots of troubles in recursive functions or if you ever want to go
multithreaded.
> It was a pointer to FStringW that was
> created in each constructor and deleted in the destructor. I managed
> to avoid an infinite loop in the constructor, but didn't realize it
> created one in the destructor, too. I wasn't able to get around that
> one. All the functions that returned FStringW returned a reference to
> the global object, so the reference had the lifetime of until another
> function uses it. That was acceptable. It would have eliminated one
> copy if it worked.
>
> So the question is: Are there any techniques for minimizing the
> number of copies that occur when returning by value?
This is mostly a job for the optimizer. In your example, the return value
optimization (RVO) might be used by the compiler, eliminating one copy
without any work from your part.
Writing simple and straightforward code often helps the optimizer to do
its work better.
If the profiler still tells you that there is a bottleneck in copy, then
you have to do something about it. One way would be to keep unchanging
parts of the object in shared use, by adding some reference counters and
so on, but this may also cause troubles in multithreading and is actually
not guaranteed to speed things up.
A better way to increase performance is to review your algorithms. The
above method looks a lot like substr(), but still copies the whole string
even if only a tiny portion is going to be used later. It should allocate
space for and copy over only the needed amount of characters.
BTW, what is the reason you are using your own string class and not
something based on std::basic_string?
>
> The ideal situation would be if the returned object could become the
> unnamed object that's passed to operator=. But I think the compiler
> would have to do that. And there's always the chance the function
> could return an expression i.e. return tfs1 + tfs2.
> My second question relates to the naming of member functions. Most
> string-altering functions I've written have two versions, one that
> returns by value and leaves the original alone, and one that alters
> the string in place. For now, I'm using:
>
> FStringW FStringW::Start(size_t end);
> void FStringW::StartIP(size_t end);
The first one should be 'const', this also helps a bit to distinguish it.
For names, I have sometimes used a convention like Foo and ApplyFoo.
But in your example, naming the functions something like Left() and
Truncate() would be much better than Start() and StartIP() ;-) And even
better would be to get rid of your class and use std::wstring or
something else based on std::basic_string instead. Selecting good names
is important for shortening the learning curve of any reader (including
yourself in the future), with std::wstring the learning curve ought to be
zero.
hth
Paavo
== 5 of 5 ==
Date: Thurs, Nov 14 2013 5:44 am
From: "Alf P. Steinbach"
On 14.11.2013 00:09, DSF wrote:
>
> I have a class I've been writing where I frequently need to return
> the class by value so that class members can be changed without
> affecting the original. The problem is all of the copying. First,
> the class has to be copied into a local instance of the class. Then,
> upon return, the local instance is copied into an unnamed instance
> that's created before the function is called, and therefore not
> destroyed when the function ends. Finally, after the function ends,
> the operator= of the target is called, yet again copying the class
> (unnamed).
Most of that copying is eliminated by the compiler.
However, for a simple and naively implemented string or array the
compiler can't get rid of the underlying O(n) element copying, since for
such a class that's the definition of the operation.
The programmer, in control of the class design, can do far better.
In your case, returning and assigning a leftmost substring, the whole
thing -- substring operation, returning, assignment -- can be done
in constant time, O(k) (also known as O(1)), and a very efficient
constant time at that, mainly[1] at the cost of making conversion to
zero-terminated string for the worst case an O(n) operation.
However, I gather you're doing this exercise for learning, and in that
case the O(k) design and implementation may be beyond your current level
of expertise, too hard to tackle. So don't fret about it. But it's worth
knowing that it's THERE, that it's obtainable, and that it's therefore
something to aim for (later) and something to compare against.
What you CAN do right now is to MEASURE.
MEASURE.
And compare to measurement of roughly the same when using e.g. std::string.
If things are too slow you can then, among other things, try to
implement a C++ "move constructor". Or a C++03 equivalent. Just ask
here, but do measure first!
Cheers, & hth.,
- Alf
Notes:
[1] Another possible cost is that the strings then become immutable. But
I see that mainly as an advantage, not a cost. It certainly both speeds
up and simplifies things, in general.
==============================================================================
TOPIC: including files best practice
http://groups.google.com/group/comp.lang.c++/t/5558ad8b3f50bf41?hl=en
==============================================================================
== 1 of 4 ==
Date: Thurs, Nov 14 2013 1:34 pm
From: ouroboros84
Please find here below a simple example. I know that a .hpp file has to include or forward declare everything it uses I wonder if it is best practice to include all .hpp files that are used in the .cpp file as well. I am asking this because I recently saw on a new project I am working on, that people tend to avoid including headers in a lot of cpp files.
In this case: is it good to include b.hpp in a.cpp? I know it has already been included by including a.hpp, but I personally feel that if a symbol appears in a .cpp, it should be included (or forward declared if possible)
a.hpp
#pragma once
#include "b.hpp"
class C; //forward declaration of C
class A
{
public:
B get_b();
private:
B _b;
C* _c;
};
a.cpp
#include "a.hpp"
//needed or I can leave it out, since B is included already in a.hpp?
#include "b.hpp"
B A::get_b()
{
return _b;
}
== 2 of 4 ==
Date: Thurs, Nov 14 2013 2:14 pm
From: Jorgen Grahn
On Thu, 2013-11-14, ouroboros84 wrote:
> Please find here below a simple example. I know that a .hpp file has
> to include or forward declare everything it uses
It doesn't /have to/ -- although it can be rather confusing if a file
which just says #include "foo.hpp" doesn't compile.
> I wonder if it is
> best practice to include all .hpp files that are used in the .cpp file
> as well. I am asking this because I recently saw on a new project I am
> working on, that people tend to avoid including headers in a lot of
> cpp files.
No, that's not best practice.
> In this case: is it good to include b.hpp in a.cpp? I know it has
> already been included by including a.hpp, but I personally feel that
> if a symbol appears in a .cpp, it should be included (or forward
> declared if possible)
My personal rule is this: if I have a pair foo.cpp/foo.hpp, I always
do a
#include "foo.hpp"
first in that cpp file. That's an automatic check that foo.hpp is
idempotent. Then you can do almost whatever you want and not end up
with a nasty effects like "I included foo.hpp from a new source file,
and had to spend half an hour finding out which other files I needed
to pull in first".
I try not to have a foo.hpp pull in a /lot/ of other headers which it
doesn't really need, but it's not a big disaster if it it pulls in a
few too many.
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
== 3 of 4 ==
Date: Thurs, Nov 14 2013 2:27 pm
From: Victor Bazarov
On 11/14/2013 4:34 PM, ouroboros84 wrote:
> Please find here below a simple example. I know that a .hpp file has
to include or forward declare everything it uses I wonder if it is best
practice to include all .hpp files that are used in the .cpp file as
well. I am asking this because I recently saw on a new project I am
working on, that people tend to avoid including headers in a lot of cpp
files.
>
> In this case: is it good to include b.hpp in a.cpp? I know it has
already been included by including a.hpp, but I personally feel that if
a symbol appears in a .cpp, it should be included (or forward declared
if possible)
>
> a.hpp
>
> #pragma once
> #include "b.hpp"
>
> class C; //forward declaration of C
>
> class A
> {
> public:
> B get_b();
> private:
> B _b;
> C* _c;
> };
>
> a.cpp
>
> #include "a.hpp"
> //needed or I can leave it out, since B is included already in a.hpp?
> #include "b.hpp"
>
> B A::get_b()
> {
> return _b;
> }
>
I second this.
I would include it since 'B' type is used in a.cpp. Cannot (and should
not) rely on 'b.hpp' being pulled in by 'a.hpp'.
Of course, it's a style question, not a necessity. If it's pulled in
twice, it should contain the double inclusion guards, etc. And if it's
not included after somebody edits 'a.hpp' file, an attempt to compile
'a.cpp' will reveal that. But I still include all those things, myself.
V
--
I do not respond to top-posted replies, please don't ask
== 4 of 4 ==
Date: Thurs, Nov 14 2013 2:29 pm
From: ouroboros84
Il giorno giovedì 14 novembre 2013 23:14:02 UTC+1, Jorgen Grahn ha scritto:
> On Thu, 2013-11-14, ouroboros84 wrote:
>
>
> > I wonder if it is
>
> > best practice to include all .hpp files that are used in the .cpp file
>
> > as well. I am asking this because I recently saw on a new project I am
>
> > working on, that people tend to avoid including headers in a lot of
>
> > cpp files.
>
>
>
> No, that's not best practice.
>
>
>
Imagine though, if now in a.cpp you had this, as you suggest:
#include "a.hpp"
//#include "b.hpp" deleted
B A::get_b()
{
return _b;
}
namespace {
B b; //I can instanciate it
// even if I don't have the header
//thanks to an im[licit inclusion from a.hpp
C = b.get_c() //I can do it as well because a.hpp -> b.hpp -> c.hpp
}
wouldn't that cause problems? imagine if someone deleted c.hpp inclusion from b.hpp, using a forward declare for returning a reference instead of a value.
in that case a.cpp wouldn't compile anymore.
I prefer to be explicit in what I have to include in every class.
for example it is rare that you need to include a <string> header, but you basically do it every time you use a string.
==============================================================================
You received this message because you are subscribed to the Google Groups "comp.lang.c++"
group.
To post to this group, visit http://groups.google.com/group/comp.lang.c++?hl=en
To unsubscribe from this group, send email to comp.lang.c+++unsubscribe@googlegroups.com
To change the way you get mail from this group, visit:
http://groups.google.com/group/comp.lang.c++/subscribe?hl=en
To report abuse, send email explaining the problem to abuse@googlegroups.com
==============================================================================
Google Groups: http://groups.google.com/?hl=en
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment