enr4ged
enr4ged

Reputation: 141

Is it better to dereference a pointer to get a value or create a local object and access the value that way?

For example say I am looping through a vector of pointers to check multiple objects and perform operations on them. I could do either of the following.

Method 1:

std::vector< Object* >::iterator it;
Object* o;
for (it = objects.begin(); it != objects.end(); ++it)
{
    o = (*it)
    if(o->GetActive())
    {
        o->method;
        o->method2;
        o->method3;
        //etc...
    }
 }

Method 2:

std::vector< Object* >::iterator it;
for (it = objects.begin(); it != objects.end(); ++it)
{
    if((*it)->GetActive())
    {
        (*it)->method;
        (*it)->method2;
        (*it)->method3;
        //etc...
    }
 }

From what I can see Method 1 has easier readability as dereferencing syntax can often complicate the readability, especially when you are doing something like:

if((*o)->CheckValue((*c)))

But creating local variables would make it much easier to read:

if(o->CheckValue(c))

But you are creating extra variables which would increase the memory cost, right?

What would the differences in performance be?

Upvotes: 0

Views: 493

Answers (3)

MSalters
MSalters

Reputation: 179819

I would in fact choose another syntax, which makes the choice irrelevant:

for (Object* o : objects)
{
  // ... body
}

Upvotes: 1

Mark Ransom
Mark Ransom

Reputation: 308196

An optimizing compiler will probably make them the same. Sometimes it's nice to assign to a variable for better readability. If the container didn't contain pointers you could use a reference instead:

std::vector< Object >::iterator it;
for (it = objects.begin(); it != objects.end(); ++it)
{
    const Object &o = (*it)
    if(o.GetActive())
    {
        o.method();
        o.method2();
        o.method3();
        //etc...
    }
 }

Edit: As Raymond points out in the comments, the compiler can't make certain optimizations if the methods might mutate the object in question. The way to fix that is to use const when possible, so I've changed my example to show it in practice. If you do this you can't call methods on the object that aren't also marked const.

Upvotes: 3

Matteo Italia
Matteo Italia

Reputation: 126787

Unless you have volatile objects around, when dealing with local objects it mostly comes down just to readability, since compilers routinely deal with this stuff by themselves.

In your particular case, *it is an operation that the compiler has to perform, and whose result will end in a register; so, it's almost sure that the compiler will leave the result in the register anyway for the next uses, thus "implicitly" creating your o variable. In other words, coming down to assembly that variable arises by itself.

It's a different situation, instead, if the compiler cannot trivially prove that it is not modified between dereferentiations (e.g. if a pointer to it - or to objects - is passed around, or if it's nonlocal) or if it's explicitly instructed to avoid this kind of optimizations (via the volatile keyword).

Upvotes: 0

Related Questions