Tuesday, December 2, 2014

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

comp.lang.c++@googlegroups.com Google Groups
Unsure why you received this message? You previously subscribed to digests from this group, but we haven't been sending them for a while. We fixed that, but if you don't want to get these messages, send an email to comp.lang.c+++unsubscribe@googlegroups.com.
Christopher Pisz <nospam@notanaddress.com>: Dec 01 05:51PM -0600

On 12/1/2014 2:54 PM, Lynn McGuire wrote:
> me know."
 
> My answer is 02.
 
> Lynn
 
Does not compile.
If it did, I am not sure what the problem would be.
 
I expect the output to be 01 and when I rewrote your snippet to a fully
compilable program it indeed was 01.
 
// Standard Includes
#include <iostream>
#include <vector>
 
 
int main()
{
std::vector<int> v;
v.push_back(0);
v.push_back(0);
 
int i = 0;
v[i++] = i++;
 
std::cout << v[0] << v[1] << std::endl;
 
return 0;
}
 
Is there some undefined behavior here that I am not aware of?
Christopher Pisz <nospam@notanaddress.com>: Dec 01 05:53PM -0600

On 12/1/2014 5:51 PM, Christopher Pisz wrote:
 
> return 0;
> }
 
> Is there some undefined behavior here that I am not aware of?
 
Derp, I mean 10. 5'o clock dyslexia.
red floyd <no.spam@its.invalid>: Dec 01 04:01PM -0800

On 12/1/2014 3:51 PM, Christopher Pisz wrote:
 
> return 0;
> }
 
> Is there some undefined behavior here that I am not aware of?
 
Yes. First of all, i is accessed and modified twice between a sequence
points
*** v[i++] = i++;
 
I'm not sure what the second category of UB that Herb refers to is.
I thought at first it might be that v[2] was being referenced, but
it's using postincrement.
Christopher Pisz <nospam@notanaddress.com>: Dec 01 06:02PM -0600

On 12/1/2014 5:53 PM, Christopher Pisz wrote:
 
> Derp, I mean 10. 5'o clock dyslexia.
 
Oh, I see, you are getting at the postfix occurring after the statement
rather than after the lhs or rhs of the statement is evaluated. Didn't
know that was undefined and made it 20 years without running into that.
I suppose that's a product of not using postfix in favor of code that
looks like it does what it actually does.
"Öö Tiib" <ootiib@hot.ee>: Dec 01 04:25PM -0800

On Monday, 1 December 2014 22:54:34 UTC+2, Lynn McGuire wrote:
> and unspecified behavior."
 
> "Rather, my question is what you would like the result to be. Please let me know."
 
> My answer is 02.
 
My answer is Other: the code is ill-formed and diagnostic is required.
JiiPee <no@notvalid.com>: Dec 02 01:09AM

On 01/12/2014 20:54, Lynn McGuire wrote:
> let me know."
 
> My answer is 02.
 
> Lynn
 
I agree with my GCC compiler: 10
 
Because it should go from left to right like we are reading it. So [i++]
first, then after that i++.
 
I am interested; why should it be something else than this? We read (and
the compiler as well) the code from top to bottom and from left to right
normally, isnt it?
 
its the same with if-statement, isnt it?
like:
if( x > 5 || y < 10 )
...
 
here if x > 5 will be checked first and if its true y < 10 is not
executed at all, isnt it? so its from left to right there as well.
JiiPee <no@notvalid.com>: Dec 02 01:25AM

On 02/12/2014 01:09, JiiPee wrote:
> ...
 
> here if x > 5 will be checked first and if its true y < 10 is not
> executed at all, isnt it? so its from left to right there as well.
 
ok, but then Visual C++ 2008 gives: 00. So obviously if compilers give
different results this should be illegal (meaning there is no standard
rule for it).
Juha Nieminen <nospam@thanks.invalid>: Dec 02 09:06AM


> std::vector<int> v;
> v.push_back(0);
> v.push_back(0);
 
I think starting to use the new standard is ok by now.
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 02 09:47AM

On Mon, 01 Dec 2014 18:02:34 -0600
> without running into that. I suppose that's a product of not using
> postfix in favor of code that looks like it does what it actually
> does.
 
It would be equally undefined if you used prefix notation. In either
case you would be modifying the same variable twice without one
modification being sequenced before the other (in C++11/14 speak) or
without an intervening sequence point (in C++98/03 speak).
 
Chris
Martijn Lievaart <m@rtij.nl.invlalid>: Dec 02 11:42AM +0100

On Tue, 02 Dec 2014 01:25:17 +0000, JiiPee wrote:
 
>> like:
>> if( x > 5 || y < 10 )
>> ...
 
No. || is defined to evaluate from left to right *and* short circuit.
 
 
> ok, but then Visual C++ 2008 gives: 00. So obviously if compilers give
> different results this should be illegal (meaning there is no standard
> rule for it).
 
It is illegal. It's called undefined behaviour.
 
M4
Juha Nieminen <nospam@thanks.invalid>: Dec 02 01:00PM

>>> if( x > 5 || y < 10 )
 
> No. || is defined to evaluate from left to right *and* short circuit.
 
Understanding the guarantee of short-cirtuiting of && and || is
important. It's both useful, and can cause unexpected results if you
are not aware.
 
For example:
 
if(foo(a) && bar(b)) ...
 
bar(b) will not be called if foo(a) returns false. If you are not aware
of this, it can come as a surprise and cause malfunction.
 
OTOH, since it's guaranteed to behave like that, it's handy because
you can now be sure that bar(b) is not called if foo(a) returns false.
This is handy eg. to first check the validity of a parameter and then
do something with the parameter only if it's valid. A typical example
would be something like:
 
if(i != 0 && a / i > 10) ...
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
Richard Damon <Richard@Damon-Family.org>: Dec 02 08:49AM -0500

On 12/1/14, 8:09 PM, JiiPee wrote:
 
> I am interested; why should it be something else than this? We read (and
> the compiler as well) the code from top to bottom and from left to right
> normally, isnt it?
 
There is an argument that a = b should evaluate b first, and then
process a to do the assignment. Also, given a + b * c some would say
that the natural order to evaluate things would be b, c, b*c, a, a+b*c.
These sort of expectations make a strict left to right become
"surprising" at times. Yes, some languages will attempt to reduce
undefined behavior by defining an order, inevitably this will sometimes
be surprising to users, and will often force the compiler to generate
less efficient code. One of the guiding principles of C that C++
inherited was that efficiency was important, and the compiler was
allowed to assume that the programmer isn't trying hard to cause
problems (if the programmer isn't following the rules, it is ok to bite
them). This causes C and C++ to have perhaps more undefined behavior
conditions than other languages, but also explains their popularity,
programmers LIKE languages that trust them and generate faster results
because of that. (Sometime when debugging problems you might wish for
help, and since "undefined behavior" can include catching the situation
and calling you a dummy, sometimes you can turn on debug modes/tools to
help you.
Martijn Lievaart <m@rtij.nl.invlalid>: Dec 02 02:50PM +0100

On Tue, 02 Dec 2014 13:00:46 +0000, Juha Nieminen wrote:
 
> something with the parameter only if it's valid. A typical example would
> be something like:
 
> if(i != 0 && a / i > 10) ...
 
Another typical example:
 
if (p && *p) ...
 
M4
Bo Persson <bop@gmb.dk>: Dec 02 05:35PM +0100

On 2014-12-02 01:02, Christopher Pisz wrote:
> know that was undefined and made it 20 years without running into that.
> I suppose that's a product of not using postfix in favor of code that
> looks like it does what it actually does.
 
So you obviously haven't used some obscure hardware, where
simultaneously reading and writing the same memory address would lock
the system up.
 
(can't remember its name right now).
 
 
BTW, v[i+1] = i+2; is the same number of characters, and a lot more obvious.
 
 
 
Bo Persson
Bo Persson <bop@gmb.dk>: Dec 02 05:40PM +0100

On 2014-12-02 02:09, JiiPee wrote:
 
> I am interested; why should it be something else than this? We read (and
> the compiler as well) the code from top to bottom and from left to right
> normally, isnt it?
 
Not really. :-)
 
The problem here is that the compiler isn't required to store the result
of the increment back into i until the end of the expression. If you
read (or write) i again before that, we don't know what will happen.
 
 
Bo Persson
JiiPee <no@notvalid.com>: Dec 02 06:30PM

On 02/12/2014 13:00, Juha Nieminen wrote:
> do something with the parameter only if it's valid. A typical example
> would be something like:
 
> if(i != 0 && a / i > 10) ...
 
yes, I have used this method a lot as well .. it is handy, just must be
100% sure it works like that first :).
 
JiiPee <no@notvalid.com>: Dec 02 06:34PM

On 02/12/2014 10:42, Martijn Lievaart wrote:
>>> if( x > 5 || y < 10 )
>>> ...
> No. || is defined to evaluate from left to right *and* short circuit.
 
I did not mean that. Also I said later: "here if x > 5 will be checked
first and if its true y < 10 is not executed at all, isnt it? so its
from left to right there as well. " So exactly what you just said....So
it was not that I did not know this.
 
I meant, that because if-statement works from left to right like that,
then the original v[] -thing should also work from left to right imo.
 
>> different results this should be illegal (meaning there is no standard
>> rule for it).
> It is illegal. It's called undefined behaviour.
 
It is defined in the standard as undefined behaviour? Just asking...
red floyd <no.spam@its.invalid>: Dec 02 10:34AM -0800

On 12/1/2014 4:25 PM, Öö Tiib wrote:
 
>> "Rather, my question is what you would like the result to be. Please let me know."
 
>> My answer is 02.
 
> My answer is Other: the code is ill-formed and diagnostic is required.
 
Other than the lack of code context (and Herb explicitly said it was a
fragment), how is it ill-formed? It's semantically incorrect, but
where is the ill-formedness to be found?
JiiPee <no@notvalid.com>: Dec 02 06:39PM

On 02/12/2014 13:49, Richard Damon wrote:
 
> There is an argument that a = b should evaluate b first, and then
> process a to do the assignment. Also, given a + b * c some would say
> that the natural order to evaluate things would be b, c, b*c, a, a+b*c.
 
yes I agree here. and b first because it is on the left hand side. But
here a not first because multiplication should be done first according
to maths, so its natural. But with arrays I do not see natural that the
right hand side should be evaluated first. Or what is the logic there?
 
JiiPee <no@notvalid.com>: Dec 02 06:42PM

On 02/12/2014 16:40, Bo Persson wrote:
> result of the increment back into i until the end of the expression.
> If you read (or write) i again before that, we don't know what will
> happen.
 
and the whole thing is an expression? ok, i was not sure about this. If
this is true then its true there should be another rule for i++ how it
works in this kind of situation. I mean if i++ is done twice before its
required to change.
 
red floyd <no.spam@its.invalid>: Dec 02 10:43AM -0800

On 12/2/2014 10:34 AM, JiiPee wrote:
>>> rule for it).
>> It is illegal. It's called undefined behaviour.
 
> It is defined in the standard as undefined behaviour? Just asking...
 
Yes.
 
Don't have the 2011 or 2014 standards, but ISO/IEC 14882:2003
specifically states 5/4 [expr]:
 
Except where noted, the order of evaluation of operands of individual
operators and subexpressions of individual expressions, and the order in
which side effects take place, is unspecified (53). *Between the
previous and next sequence point, a scalar object shall have its stored
value modified at most once by the evaulation of an expression*.
Furthermore, the prior value shall be accessed only to determine the
value to be stored. The requirements of this paragraph shall be met for
each allowable ordering of the subexpressions of a full expression;
*otherwise the behavior is undefined*.
 
(emphases mine)
JiiPee <no@notvalid.com>: Dec 02 06:45PM

On 02/12/2014 16:35, Bo Persson wrote:
 
> BTW, v[i+1] = i+2; is the same number of characters, and a lot more
> obvious.
 
Whatever it is, in my opinion this kind of confusing code is not a good
practice. better to create temporary variables and use them instead -- I
mean one of them should be set using a temp variable before this and
then used.
red floyd <no.spam@its.invalid>: Dec 02 10:45AM -0800

On 12/2/2014 10:43 AM, red floyd wrote:
 
> each allowable ordering of the subexpressions of a full expression;
> *otherwise the behavior is undefined*.
 
> (emphases mine)
 
Further, the remainder of that paragraph explicitly gives
 
i = v[i++];
 
as an example of UB.
red floyd <no.spam@its.invalid>: Dec 02 10:46AM -0800

On 12/2/2014 10:42 AM, JiiPee wrote:
 
> this is true then its true there should be another rule for i++ how it
> works in this kind of situation. I mean if i++ is done twice before its
> required to change.
 
It's explicitly UB. See the quote from the (2003) standard that I
posted upthread.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Dec 02 05:49PM

Hi,
 
Is the following undefined behaviour?
 
int i = 0;
++++i;
 
Here i is modified twice in the same expression so I think it is UB but
I'm not 100% sure.
 
/Flibble
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: