1

Studying some sources I often came to see this: (Part of the real source)

void CUserMng::AddText( LPCTSTR szMessage )
{
    map<u_long,CUser*>::iterator it;
    for( it = m_users.begin(); it != m_users.end(); ++it )
    {
        CUser *pUser = it->second;
        if( !IsValidObj( pUser ) )
            continue;

            (pUser)->AddTextNotice( szMessage );
    }
}

What do the parentheses around pUser means?

I came up with:

struct bar
{
    int value;
}

void foo()
{
    bar *ptr = NULL; //new bar;
    (ptr)->value = 1;
    //delete bar
}

My guess was that a call with parentheses "(ptr)" was to prevent a call to be made if the pointer was invalid, but it seems its not. Another example I often see is:

classB* ptr = new classB;
((classA*)ptr)->callfunctionfromclassA;
sbi
  • 219,715
  • 46
  • 258
  • 445
Vinícius
  • 15,498
  • 3
  • 29
  • 53
  • 1
    I'm 99% sure the first set of parens don't do anything. But I haven't written C++ for a long while, so won't post this as an answer. – Gene Aug 25 '12 at 00:25
  • 5
    In the first case they're just coming to give the pointer a hug... – ta.speot.is Aug 25 '12 at 00:27

4 Answers4

4

The parentheses are not doing anything in the first example.

In the second they are needed, as the meaning of the expression changes if they are omitted. Member selection via the -> operator has higher precedence than the type cast. So, if you were to write

(classA*)ptr->callfunctionfromclassA();

it means you'd be casting the return value of the ptr->callfunctionfromclassA() call to a classA *. As written in the example, you're first casting ptr to classA * type and then invoking callfunctionfromclassA;

Praetorian
  • 106,671
  • 19
  • 240
  • 328
2

Parentheses in your first example do nothing.

In the second example, parens are casting the pointer before being dereferenced.

TJD
  • 11,800
  • 1
  • 26
  • 34
  • 1
    In the second case the parenthesis are not just to make it clear, but to affect how the expressions are bound. Without the parenthesis, the expression would bind as `(classA*)(ptr->callfunctionfromclassA())` which does not seem to be the intention. – David Rodríguez - dribeas Aug 25 '12 at 00:32
2

What do the parentheses around pUser means?

It means the guy who wrote that code had no idea what he was doing.

Another example I often see is:

classB* ptr = new classB;
((classA*)ptr)->callfunctionfromclassA;

It means whoever wrote that still writes C with Classes, a language that should have been dead for 15 years now.

sbi
  • 219,715
  • 46
  • 258
  • 445
  • What do you mean by `It means whoever wrote that still writes C with Classes, a language that should have been dead for 15 years now.`? – Vinícius Aug 25 '12 at 01:23
  • @Vinao, presumably he means that it's more idiomatic to use virtual functions? Anyway, the first case could have come about through refactoring. – Antimony Aug 25 '12 at 02:10
  • 1
    @vinaoxd: It means that the code is bad. If `classB` is derived from `classA`, then the cast is unnecessary. If it isn't, then this is plain wrong and leads to _[Undefined Behavior](http://stackoverflow.com/a/1553407/140719)_. Besides that, using C-style casts is dangerous, you should rather be using C++-style casts. (_C with Classes_ was the unofficial title of a project of a certain Dane at AT&T in the 80s, that later turned into C++. Since then, C++ has made gigantic leaps towards becoming a safer and better language than _C with Classes_ ever was. But some are still stuck in the 80s.) – sbi Aug 25 '12 at 09:18
0

In the first case, the parenthesis are redundant. They could be the result of refactoring or style preferences.

In the second case, it means to cast ptr to a classA* before dereferencing it. Without the parenthesis, you'd have to know the operator precedences to tell what happens, so the code is much clearer and safer with them.

Antimony
  • 37,781
  • 10
  • 100
  • 107
  • 1
    This is not quite right. Without the second pair, the type cast works on the whole quantity `ptr->callfunctionfromclassA`. This is a well-defined operation and an often-used idiom. – Gene Aug 25 '12 at 00:29
  • @Gene, I never said the parenthesis weren't required in the second case. My remark about operator precedence was supposed to indicate that possibility. Sorry about the misunderstanding. – Antimony Aug 25 '12 at 02:08