Performance or other differences on if expression?

J

jeffc

Is there any difference between these 2?

int i = f();
if ( i )

and

int i;
if ( i = f() )

It seems like the latter would save the assignment if i was initialized on
the definition anyway? Would it work differently for class types or other
types?
 
J

Jakob Bieling

jeffc said:
Is there any difference between these 2?

int i = f();
if ( i )

and

int i;
if ( i = f() )

It seems like the latter would save the assignment if i was initialized on
the definition anyway? Would it work differently for class types or other
types?

I did not quite understand the first question, but for built-in types I
do not think you will notice any performance difference. Basically, you are
asking about the difference between:

int i = 0;

and

int i;
i = 0;

For class types you may very well notice a performance hit, since the
class is first default constructed and then assigned to, whereas in the
former snippet you have only one step, the contruction. But this also
depends on the class.

hth
 
J

jeffc

Jakob Bieling said:
I did not quite understand the first question, but for built-in types I
do not think you will notice any performance difference. Basically, you are
asking about the difference between:

int i = 0;

and

int i;
i = 0;

My question was basically: is that what it boils down to? Or is there some
other factor involved specifically with if statements I'm not aware of that
would cause my first 2 examples to be treated differently?
 
J

Jonathan Mcdougall

Is there any difference between these 2?
int i = f();
if ( i )

and

int i;
if ( i = f() )

It seems like the latter would save the assignment if i was
initialized on the definition anyway?

No. In both cases, f() will be evaluated first and then the result will be
affected to 'i'.


Jonathan
 
J

Jakob Bieling

jeffc said:
initialized types

My question was basically: is that what it boils down to? Or is there some
other factor involved specifically with if statements I'm not aware of that
would cause my first 2 examples to be treated differently?


What factor do you have in mind that would cause them to be treated
differently? Your two examples produce the exact same result, and might even
produce the same code with a decent enough optimizer.

Hope I helped this time
 
A

Andrew Koenig

jeffc said:
Is there any difference between these 2?

int i = f();
if ( i )

and

int i;
if ( i = f() )

It seems like the latter would save the assignment if i was initialized on
the definition anyway? Would it work differently for class types or other
types?

If we ignore the fact that "i" has a built-in type, thereby opening the
possibility of user-defined operators, I can see two significant differences
between the two forms:

1) In the second form, "i" takes on two distinct values: The value with
which it is initialized as part of its definition (undefined for type int,
but defined for other types), and the value assigned to it from f(). In the
first form, "i" takes on only the latter value. This difference might be
significant if "i" is of a type that has no default value (which would
render the second form ill-formed), or if intializing "i" takes significant
time.

2) In the second form, "=" might be a user-defined operator. In the first
form, it can't be.
 
J

jeffc

Jakob Bieling said:
What factor do you have in mind that would cause them to be treated
differently? Your two examples produce the exact same result, and might even
produce the same code with a decent enough optimizer.

I don't know. I didn't have anything in mind - I just wondered if you did
:)
 
J

jeffc

Jonathan Mcdougall said:
No. In both cases, f() will be evaluated first and then the result will be
affected to 'i'.

What I meant was that in the former case, there is not both an
initialization and an assignment. Or, you might say it does both in one
step. In the latter case, you are definitely doing an assignment, but isn't
i going to be initialized to something, as well?
 
J

jeffc

Andrew Koenig said:
If we ignore the fact that "i" has a built-in type, thereby opening the
possibility of user-defined operators...

2) In the second form, "=" might be a user-defined operator. In the first
form, it can't be.

Good point, but I'm not sure I understand fully. Are you saying that given
class A{...};
A a = f(); // first case
if (a = f()) // second case

that the first case is equivalent to
A a(f());
and in fact implemented as such, and therefore the user-defined "=" operator
is irrelevant?
 
E

E. Robert Tisdale

jeffc said:
Is there any difference between these two examples?

int i = f(); // example 1
if (i) { /* . . . */ }

and

int i; // example 2
if (i = f()) { /* . . . */ }

It seems like the latter would save the assignment
if i was initialized on the definition anyway?

It is poor programming practice to declare an undefined variable
as you have done in example 2.
Would it work differently for class types or other types?

class X {
// . . .
public:
operator bool(void) const;
// . . .
};

X f(void);

X x;
if (x = f()) { /* . . . */ }

In general, this will require a call to the default constructor
and then a call to the assignment operator
to copy the result of f() into x.
 
J

Jonathan Mcdougall

int i = f();
What I meant was that in the former case, there is not both an
initialization and an assignment. Or, you might say it does both in
one step.

No. What exactly happens is implementation defined, that is,

int i = f();

could result in

int i(f()); //copy-ctor

or

int i; // nothing
i = f(); // assignment

the former being an optional optimization.
In the latter case, you are definitely doing an
assignment,

Not necessarily.
but isn't i going to be initialized to something, as well?

No, with

int i;

'i' is _not_ initialized and using it would result in undefined behavior.

class T { ... };
class U { ... };

T f();

int main()
{
U u = f();
// could mean
// U u( f() );
// U u( some_ud_conversion(f()) );
// U u; u.operator=( f() );
// U u; u.operator=( some_ud_conversion(f()) );

U u;
u = f();
// could mean
// U u( f() );
// U u( some_ud_conversion(f()) );
// U u; u.operator=( f() );
// U u; u.operator=( some_ud_conversion(f()) );

}

As you noticed, both can result to the same thing or not, depending on the
compiler and its optimizations. A good compiler will make the second
statement look like the first one and the same compiler would make the first
one look like

U u(f());

or

U u( some_ud_conversion(f()) );

if it is possible in that case.

some_ud_conversion could be like a ctor taking a T or if T can be converted
to a U...

BTW, isn't something like that called 'premature optimization'? If you
don't know whether it speeds things up or not, maybe you should wait a bit
or use a profiler to check the real bottlenecks in your program. If it is
only by curiosity, well, that is a good thing.


Jonathan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top