I have finally tracked down a problem that has been bugging me for a
while, and it appears that I had been overlooking it because I was
confident that I knew what this behaviour should be...
The problem came when I tried to process my function taking an
iterator range as follows
void func(iterator begin, iterator end)
{
for( ; begin != end; ++begin)
{
// do stuff
}
}
To me this seemed sensible. I don't know where I first saw the form,
but I had been using it in VC6 (I know this is no indication of
compliance) for years with the result that i expected in that each
item between begin (included) and end (excluded).
In simple terms it is much like the loop
int i = 0;
for ( ; i != 2; ++i)
{
int j = i;
}
I expected j to get set to 0, then 1 then for the loop to end, but
this is not how my compiler is behaving. j first gets set to 1 and
there is only ever one pass through. i is being incremented on the
first pass. If I create an extra copy of the iterated value
for (int k = i; k != 2; ++k) ...
I get the behaviour I was anticipating.
Could anyone clear this up for me. What should the behaviour be? Is
dropping the copy bad practice?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
rhphotography.net (2)
|
3/26/2010 7:34:25 AM |
|
Richard Howard wrote:
> I have finally tracked down a problem that has been bugging me for a
> while, and it appears that I had been overlooking it because I was
> confident that I knew what this behaviour should be...
>
> The problem came when I tried to process my function taking an
> iterator range as follows
>
> void func(iterator begin, iterator end)
> {
> for( ; begin != end; ++begin)
> {
> // do stuff
> }
> }
>
> To me this seemed sensible. I don't know where I first saw the form,
> but I had been using it in VC6 (I know this is no indication of
> compliance) for years with the result that i expected in that each
> item between begin (included) and end (excluded).
>
> In simple terms it is much like the loop
>
> int i = 0;
> for ( ; i != 2; ++i)
> {
> int j = i;
> }
>
> I expected j to get set to 0, then 1 then for the loop to end, but
> this is not how my compiler is behaving. j first gets set to 1 and
> there is only ever one pass through. i is being incremented on the
How do you know this? Walking through with a debugger? Inspecting
assembly instructions? I assume you are doing either of these with an
optimized build.
> first pass. If I create an extra copy of the iterated value
>
> for (int k = i; k != 2; ++k) ...
>
> I get the behaviour I was anticipating.
>
> Could anyone clear this up for me. What should the behaviour be?
The behavior should be that which gives the same result as naively looping.
> Is dropping the copy bad practice?
Why would it be? We end up with the same result with many fewer
instructions and in far less time. Seems like a good thing.
Jeff
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Jeff
|
3/26/2010 11:32:36 AM
|
|
Richard Howard wrote:
> I have finally tracked down a problem that has been bugging me for a
> while, and it appears that I had been overlooking it because I was
> confident that I knew what this behaviour should be...
>
> The problem came when I tried to process my function taking an
> iterator range as follows
>
> void func(iterator begin, iterator end)
> {
> for( ; begin != end; ++begin)
> {
> // do stuff
> }
> }
>
> To me this seemed sensible. I don't know where I first saw the form,
> but I had been using it in VC6 (I know this is no indication of
> compliance) for years with the result that i expected in that each
> item between begin (included) and end (excluded).
Let me answer your question with an integer counter first and then with
iterators.
>
> In simple terms it is much like the loop
>
> int i = 0;
> for ( ; i != 2; ++i)
> {
> int j = i;
> }
>
> I expected j to get set to 0, then 1 then for the loop to end, but
> this is not how my compiler is behaving. j first gets set to 1 and
> there is only ever one pass through. i is being incremented on the
> first pass. If I create an extra copy of the iterated value
>
> for (int k = i; k != 2; ++k) ...
>
> I get the behaviour I was anticipating.
This is all due to the optimization. The compiler is smart enough to see
that the body of the loop does not have any side-effects and that it's
safe to just collapse the loop to a single assignment of 1 to j;
In your second loop (with k) it all depends on what the compiler can
assume about the starting value of i. I guess that there was some code
between the loops that could modify i and in that case the compiler
can't make any assumptions about it's starting value unlike in the first
loop where all values are statically known.
Now the example with iterators is a lot more complicated. I'm actually
surprised at the outcome you describe. I can think of only one case when
the compiler could eliminate that loop and that is when iterators are
actually pointers and the body of the loop can be statically proven to
not have any side effects during each iteration.
>
> Could anyone clear this up for me. What should the behaviour be? Is
> dropping the copy bad practice?
>
HTH,
Andy.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Andy
|
3/26/2010 11:36:06 AM
|
|
Richard Howard <rhphotography.net@googlemail.com> wrote:
>
> I have finally tracked down a problem that has been bugging me for a
> while, and it appears that I had been overlooking it because I was
> confident that I knew what this behaviour should be...
>
> The problem came when I tried to process my function taking an
> iterator range as follows
>
> void func(iterator begin, iterator end)
> {
> for( ; begin != end; ++begin)
> {
> // do stuff
> }
> }
>
> To me this seemed sensible. I don't know where I first saw the form,
> but I had been using it in VC6 (I know this is no indication of
> compliance) for years with the result that i expected in that each
> item between begin (included) and end (excluded).
Your expectation is correct, but only if neither begin nor end are
modified within the loop, and the container they are iterators of is not
modified during the loop.
> In simple terms it is much like the loop
>
> int i = 0;
> for ( ; i != 2; ++i)
> {
> int j = i;
> }
>
> I expected j to get set to 0, then 1 then for the loop to end, but
> this is not how my compiler is behaving. j first gets set to 1 and
> there is only ever one pass through. i is being incremented on the
> first pass.
For the specific code above, that is acceptable behavior. The only
effect of the loop construct above is that it makes i == 2, as long as
the generated object code does that, then it is correct.
> If I create an extra copy of the iterated value
>
> for (int k = i; k != 2; ++k) ...
>
> I get the behaviour I was anticipating.
>
> Could anyone clear this up for me. What should the behaviour be? Is
> dropping the copy bad practice?
Maybe if you posted more complete examples?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Daniel
|
3/26/2010 11:46:03 AM
|
|
On Mar 26, 1:34 pm, Richard Howard <rhphotography....@googlemail.com>
wrote:
> I have finally tracked down a problem that has been bugging me for a
> while, and it appears that I had been overlooking it because I was
> confident that I knew what this behaviour should be...
>
> The problem came when I tried to process my function taking an
> iterator range as follows
>
> void func(iterator begin, iterator end)
> {
> for( ; begin != end; ++begin)
> {
> // do stuff
> }
>
> }
>
> To me this seemed sensible. I don't know where I first saw the form,
> but I had been using it in VC6 (I know this is no indication of
> compliance) for years with the result that i expected in that each
> item between begin (included) and end (excluded).
>
> In simple terms it is much like the loop
>
> int i = 0;
> for ( ; i != 2; ++i)
> {
> int j = i;
>
> }
>
> I expected j to get set to 0, then 1 then for the loop to end, but
> this is not how my compiler is behaving. j first gets set to 1 and
> there is only ever one pass through. i is being incremented on the
> first pass. If I create an extra copy of the iterated value
>
> for (int k = i; k != 2; ++k) ...
>
> I get the behaviour I was anticipating.
>
> Could anyone clear this up for me. What should the behaviour be? Is
> dropping the copy bad practice?
{ edits: quoted banner removed. please keep readers in mind when quoting. -mod }
what kind of container does the iterator belong to?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Musaul
|
3/26/2010 11:46:49 AM
|
|
|
4 Replies
127 Views
(page loaded in 0.068 seconds)
Similiar Articles: Behaviour of system calls when multibyte characters are passed ...Hi, What would be the behaviour if a path containing multibyte characters is passed to functions like execl that expect a const char*? Would it be h... Strange behaviour with sockets, SetSockOpt and Solaris 10 - comp ...I all. We are having a huge problem trying to move from Solaris 9 to Solaris 10, specifically with the SetSockOpt function. One of our processes... Question regarding pragma translate_off/on , synthesis_off/on ...Hi all, Can anyone tell me what should be the ideal behaviour for a synthesis tool regarding the pragmas translate_off/on and synthesis_off/on ? My qu... Strange df and du behavior - comp.unix.solarisHello, Can someone explain strange behavior of "df" and "du" commands I have on my Solaris 10 servers with sparse zones? Zones have /home inherited... fcntl() - ioctlsocket() - comp.unix.programmerint iMode = 1; ioctlsocket(sd, FIONBIO, (u_long FAR*) &iMode) contains the same behaviour for win32 systems. Many kind greetings, --wim Application Behaviour? - comp.graphics.api.openglHello, I have coded a custom(4 way) splitter window, which displays OpenGL in each window/viewport. I was having problems getting things to run smoot... selection problem for checkboxes in uitable - comp.soft-sys.matlab ...Or do you at least see the described behavior if you run the code-snipplet on your machines? Cheers, Adrian Code: %demo: uitable checkbox selection problem ... Serialization in Matlab - comp.soft-sys.matlabBSON I would have to look at further, but I do not see at the moment how one would encode, say, behaviour for variables in such a way that when the remote system ... Strange behaviour with wglUseFontBitmaps - comp.graphics.api ...Hi, Hope this is on-topic here as it's about a wgl function rather than portable OpenGL code (if not, please can someone suggest a more appropr... Different behavior of FSM in same simulation - comp.arch.fpga ...Hi! I'm having a small problem with simulations using Xilinx ISE 11.1. In my code there are some FSM which were declared like: process(clk, rst) beg... TxABA | Texas Association for Behavior AnalysisThe mission of the Texas Association for Behavior Analysis is to advance the science and application of behavior analysis to improve the world in which we live. OntabaONTABA Ontario ABA ... ONTABA, the Ontario Association for Behaviour Analysis, is an Affiliate Chapter of the Association for Behaviour ... 7/25/2012 4:28:24 PM
|