Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: XE8 Rad studio, difference between object x; and object x (); declarations


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 1 - Last Post: Jul 20, 2015 11:37 AM Last Post By: Remy Lebeau (Te...
Jan Dijkstra

Posts: 206
Registered: 11/4/99
XE8 Rad studio, difference between object x; and object x (); declarations  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 15, 2015 7:31 AM
Hello,

I've implemented a simple class, with a couple of constructors, like so

struct PACKAGE SNumValue : public SNumUnit
{
  TNumType numRepresentation;
  bool     fixedPrecision;
  bool     isNegative;
  bool     conversionFailed;
 
  union
  {
    int           intValue;
    __int64       int64Value;
    double        floatValue;
    TDateTimeBase date;
  };
 
       __fastcall SNumValue (void);
       __fastcall SNumValue (TNumUnitType type);
       __fastcall SNumValue (TNumUnitType type, int decimals);
       __fastcall SNumValue (SNumUnit const &source);
       __fastcall SNumValue (SNumValue const &source);
       __fastcall SNumValue (bool source);
       __fastcall SNumValue (int source);
       __fastcall SNumValue (__int64 source);
       __fastcall SNumValue (double source);
       __fastcall SNumValue (TDateTime const &source);
 
     // left out a bunch of member function declarations
};


Now I want to use this class in a function, like so

SNumValue  __fastcall GetNumValue (void)
{
  SNumValue result;
 
  TLicListItem *current = GetCurrent ();
  if (current)
  {
    if (FFieldIndex < 0)  FFieldIndex = current->IndexOfField (FFieldName);
    if (FFieldIndex >= 0) result      = current->FieldValue [FFieldIndex];
  }
 
  return result;
}


This works. However, if I change SNumValue result; into SNumValue result (); it fails to compile, stating at the "result = " line that an LValue is required. And I wonder why that is. I know that declaring it as SNumValue result; invokes the default constructor, but shouldn't SNumValue result (); do that too?

If I add a second declaration SNumValue result2 (); and change the return result; into return result2; and compile to assembly (which now succeeds, as the LValue error is now not triggered), I can clearly see a difference in code generated for the return statement, but I'm at a loss as to why that is.

this is the assembly code for return result;
 
	mov       edx,esp
	mov       eax,edi
	call      @@licSystem@SNumValue@$bctr$qqrrx19licSystem@SNumValue
	mov       eax,edi
 
and this is the assembly code, when I change to return result2;
 
	mov       ecx,offset @@licSystem@result2$qv
	mov       eax,edi
	test      ecx,ecx
	setne     dl
	and       edx,1
	call      @@licSystem@SNumValue@$bctr$qqro
	mov       eax,edi

Two different constructor calls entirely, where I expected (given the return statements in both cases) a copy constructor for both. Also, the declaration SNumValue result2 (); generates no code, not even a constructor call.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: XE8 Rad studio, difference between object x; and object x ();declarations  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 20, 2015 11:37 AM   in response to: Jan Dijkstra in response to: Jan Dijkstra
Jan wrote:

However, if I change SNumValue result; into SNumValue result ();
it fails to compile, stating at the "result = " line that an LValue is
required. And I wonder why that is.

You are encountering a language ambiquity known as "Most Vexing Parse":

https://en.wikipedia.org/wiki/Most_vexing_parse

I know that declaring it as SNumValue result; invokes the default
constructor, but shouldn't SNumValue result (); do that too?

No, actually. It is required by the C++ spec to be interpreted as a declaration
of a function named result taking no parameters as input and returning an
SNumValue as output.

Two different constructor calls entirely, where I expected (given the
return statements in both cases) a copy constructor for both. Also,
the declaration SNumValue result2 (); generates no code, not even
a constructor call.

Because it is not declaring a variable at all, it is declaring a function.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02