Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Is this compiler specific or a C rule? (http://www.velocityreviews.com/forums/t722231-is-this-compiler-specific-or-a-c-rule.html)

aleksa 05-05-2010 10:05 AM

Is this compiler specific or a C rule?
 
Suppose I'm given a ptr to RECT and am modifying the RECT in a loop:

V1:

void ModifyRect (RECT* prect);
{
while (cond) {
if (newleft < prect->left) prect->left = newleft;
.
.
.
}
}


V2:

void ModifyRect (RECT* prect);
{
RECT rect;

while (cond) {
if (newleft < rect.left) rect.left = newleft;
.
.
.
}

*prect = rect;
}

(newleft is read sequentially from somewhere)

Compiler generated code for V1 accesses memory all the time,
while V2 holds everything in registers and only updates
the prect when finished.

I don't see a reason why both versions aren't coded the same.
(there is no VOLATILE anywhere...)

Just wondering, is this compiler specific or a C rule?

Willem 05-05-2010 10:14 AM

Re: Is this compiler specific or a C rule?
 
aleksa wrote:
) Suppose I'm given a ptr to RECT and am modifying the RECT in a loop:
)
) V1:
)
) void ModifyRect (RECT* prect);
) {
) while (cond) {
) if (newleft < prect->left) prect->left = newleft;
) .
) .
) .
) }
) }
)
)
) V2:
)
) void ModifyRect (RECT* prect);
) {
) RECT rect;
)
) while (cond) {
) if (newleft < rect.left) rect.left = newleft;
) .
) .
) .
) }
)
) *prect = rect;
) }
)
) (newleft is read sequentially from somewhere)
)
) Compiler generated code for V1 accesses memory all the time,
) while V2 holds everything in registers and only updates
) the prect when finished.
)
) I don't see a reason why both versions aren't coded the same.
) (there is no VOLATILE anywhere...)
)
) Just wondering, is this compiler specific or a C rule?

I think this is compiler specific, although C comes into it.

Does the other code in the while-loop call any other functions ?

If so, then it's a lot more difficult for the compiler to prove
that the pointed-to data isn't used or changed in the meantime
(which is kind-of a C rule) while in the V2 code, the compiler
knows that nothing outside the function can influence the struct.
(which is also kind-of a C rule).


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

aleksa 05-05-2010 10:29 AM

Re: Is this compiler specific or a C rule?
 
> Does the other code in the while-loop call any other functions ?

No.

bart.c 05-05-2010 10:50 AM

Re: Is this compiler specific or a C rule?
 

"aleksa" <aleksazr@gmail.com> wrote in message
news:ea36a697-ff3a-42a4-b209-27cfdcca538c@k41g2000yqb.googlegroups.com...
> Suppose I'm given a ptr to RECT and am modifying the RECT in a loop:
>
> V1:
>
> void ModifyRect (RECT* prect);
> {
> while (cond) {
> if (newleft < prect->left) prect->left = newleft;


> V2:
>
> void ModifyRect (RECT* prect);
> {
> RECT rect;
>
> while (cond) {
> if (newleft < rect.left) rect.left = newleft;


> *prect = rect;
> }
>
> (newleft is read sequentially from somewhere)
>
> Compiler generated code for V1 accesses memory all the time,
> while V2 holds everything in registers and only updates
> the prect when finished.
>
> I don't see a reason why both versions aren't coded the same.
> (there is no VOLATILE anywhere...)
>
> Just wondering, is this compiler specific or a C rule?


V1 is more difficult to optimise (for a start, you have a pointer *and* rect
to deal with, instead of just rect). And while you say no other functions
are called.. is 'newleft' updated during the loop?

What about a V3 where you pass and return the rect by value?

--
Bartc


Eric Sosman 05-05-2010 01:16 PM

Re: Is this compiler specific or a C rule?
 
On 5/5/2010 6:05 AM, aleksa wrote:
> Suppose I'm given a ptr to RECT and am modifying the RECT in a loop:
>
> V1:
>
> void ModifyRect (RECT* prect);


Assuming RECT is suitably declared, this is a valid declaration
for a function. It is not, however, a valid beginning for a function
definition. Two thoughts: Lose the semicolon, and make a habit of
posting real code rather than messed-up paraphrases.

> {
> while (cond) {
> if (newleft< prect->left) prect->left = newleft;
> .
> .
> .
> }
> }
>
>
> V2:
>
> void ModifyRect (RECT* prect);


Well, at least you're consistent.

> {
> RECT rect;
>
> while (cond) {
> if (newleft< rect.left) rect.left = newleft;
> .
> .
> .
> }
>
> *prect = rect;
> }
>
> (newleft is read sequentially from somewhere)
>
> Compiler generated code for V1 accesses memory all the time,
> while V2 holds everything in registers and only updates
> the prect when finished.
>
> I don't see a reason why both versions aren't coded the same.
> (there is no VOLATILE anywhere...)
>
> Just wondering, is this compiler specific or a C rule?


Most likely, the difference is that in V2 the compiler knows
that `rect' is distinct from all other variables in the program.
In V1, `prect' might be pointing pretty much anywhere, including
at something that overlaps `newleft' or some other variable. The
"C rule" would be that if you store a new value in something via
a pointer and then access that something by name, the access by
name and the access by pointer must agree on what's there.

You're on a game show, with three other people hidden behind
three doors. You know that Alice has ten dollars, Betty has twelve,
and Carol has eight, but you don't know who's behind which door.
The game show host pushes a dollar bill through the slot of Door
Number Two (access via pointer). How much money does Carol have?
To find out, you must ask her (access via name).

--
Eric Sosman
esosman@ieee-dot-org.invalid

William Hughes 05-05-2010 01:47 PM

Re: Is this compiler specific or a C rule?
 
On May 5, 7:05*am, aleksa <aleks...@gmail.com> wrote:
> Suppose I'm given a ptr to RECT and am modifying the RECT in a loop:
>
> V1:
>
> void ModifyRect (RECT* prect);
> {
> * * while (cond) {
> * * * * if (newleft < prect->left) prect->left = newleft;
> * * * * .
> * * * * .
> * * * * .
> * * }
>
> }
>
> V2:
>
> void ModifyRect (RECT* prect);
> {
> * * RECT rect;
>
> * * while (cond) {
> * * * * if (newleft < rect.left) rect.left = newleft;
> * * * * .
> * * * * .
> * * * * .
> * * }
>
> * * *prect = rect;
>
> }
>
> (newleft is read sequentially from somewhere)
>
> Compiler generated code for V1 accesses memory all the time,
> while V2 holds everything in registers and only updates
> the prect when finished.
>
> I don't see a reason why both versions aren't coded the same.
> (there is no VOLATILE anywhere...)
>



Well, for one thing, the two functions do something very
different. In V2 you never actually initialize rect
and you ignore the initial values of prect!
I think you left out a

rect = *prect;

> Just wondering, is this compiler specific or a C rule?


This is compiler specific. That said it is easier
for the compiler to put a local into registers, than to
put stuff pointed to by a parameter into registers.

- William Hughes

aleksa 05-05-2010 02:08 PM

Re: Is this compiler specific or a C rule?
 
> Well, at least you're consistent.

I got the will-power from copy & paste ;)


> Most likely, the difference is that in V2 the compiler knows
> that `rect' is distinct from all other variables in the program.
> In V1, `prect' might be pointing pretty much anywhere, including
> at something that overlaps `newleft' or some other variable.


Yes, I can understand the compilers POW here.



aleksa 05-05-2010 02:23 PM

Re: Is this compiler specific or a C rule?
 
My first post was supposed to show the problem,
without going too much into details.

For the sake of completeness, here are the sources:

void V1 (POINT* src, RECT* prect)
{
POINT pt;

prect->left = INT_MAX;
prect->bottom = INT_MAX;
prect->right = INT_MIN;
prect->top = INT_MIN;

while (1) {
pt.x = src->x;
pt.y = src->y;
src++;

if (pt.x == 0) break;

if (pt.x < prect->left) prect->left = pt.x;
if (pt.x > prect->right) prect->right = pt.x;

if (pt.y < prect->bottom) prect->bottom = pt.y;
if (pt.y > prect->top) prect->top = pt.y;
}
}

void V2 (POINT* src, RECT* prect)
{
POINT pt;
RECT rect;

rect.left = INT_MAX;
rect.bottom = INT_MAX;
rect.right = INT_MIN;
rect.top = INT_MIN;

while (1) {
pt.x = src->x;
pt.y = src->y;
src++;

if (pt.x == 0) break;

if (pt.x < rect.left) rect.left = pt.x;
if (pt.x > rect.right) rect.right = pt.x;

if (pt.y < rect.bottom) rect.bottom = pt.y;
if (pt.y > rect.top) rect.top = pt.y;
}

*prect = rect;
}



Francis Moreau 05-05-2010 09:24 PM

Re: Is this compiler specific or a C rule?
 
On 5 mai, 15:16, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
[snip]
> In V1, `prect' might be pointing pretty much anywhere, including
> at something that overlaps `newleft' or some other variable.


Do you mean that 'prect' whose type is pointer on 'RECT' can overlap
'newleft' whose type is obviously different from 'RECT' one ?

Does the C rules allow this ?

Nobody 05-06-2010 03:28 AM

Re: Is this compiler specific or a C rule?
 
On Wed, 05 May 2010 16:23:19 +0200, aleksa wrote:

> My first post was supposed to show the problem,
> without going too much into details.
>
> For the sake of completeness, here are the sources:
>
> void V1 (POINT* src, RECT* prect)


The compiler must assume that the data referenced via src can overlap
the data referenced via prect. So modifying e.g. prect->left could modify
elements of src which will be used later.

If you copy *prect to a local variable and modify that, the compiler
is free to assume that the data referenced via src doesn't overlap the
local variable (in practice, it's possible to cause this to happen, but
only by using mechanisms which the standard specifies as invoking
undefined behaviour).



All times are GMT. The time now is 06:32 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.