Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

This code shouldn't run. Heck! It shouldn't even compile!

75 views
Skip to first unread message

DSF

unread,
Oct 2, 2014, 9:48:20 PM10/2/14
to
Hello group!

Whilst perusing my string class for another posting, I encountered
code that I originally thought was in error. I see now how it is
working, but there is still one aspect that puzzles me. That's why
this is being posted instead of being dumped into the bit bucket.

First, the class (FString, which is a template class) contains,
among others, four dual string parameter constructors. One for each
permutation of const FString<CH>& and const char *. They construct a
string object that is a left-to-right concatenation of the two
parameters.

template <class CH> class FString
{
public:
// One of four:
FString(const FString<CH>& string1, const FString<CH>& string2, bool
casesensitive = csdefault);

// The + operator is overloaded in the same manner, as in:
// One of four:
friend const FString<CH> operator+(const FString<CH>& str1, const
FString<CH>& str2);

}; // Within the class.

And outside:
template <class CH> const FString<CH> operator+(const FString<CH>&
str1, const FString<CH>& str2)
{
return FString<CH>(str1, str2);
}

I first thought the error here is that I was calling a constructor
to do the concatenation. But I see now I am merely creating an
unnamed object. Since the object is returned by value, the scope of
the object is no problem, but I'm still left with one puzzler:

Constructors are not declared (defined? I always get those two
mixed-up!) with a return value. If I recall correctly you are not
supposed to use a constructor as an rvalue. (As an aside, I know that
every constructor created with my ancient Borland C/C++ 5.xx returns
"this". Disassembly proves it.

So have I forgotten something and this is legal code, or just
something my compiler is allowing?

If it's legal, my guess would be that I'm not returning the value of
the constructor, but rather a copy of the temporary object the
constructor constructed.

Thanks for any help,
DSF
"'Later' is the beginning of what's not to be."
D.S. Fiscus

Paavo Helde

unread,
Oct 3, 2014, 2:18:15 AM10/3/14
to
DSF <nota...@address.here> wrote in
news:89mr2a1ldodl5orcn...@4ax.com:

> template <class CH> const FString<CH> operator+(const FString<CH>&
> str1, const FString<CH>& str2)
> {
> return FString<CH>(str1, str2);
> }
>
> I first thought the error here is that I was calling a constructor
> to do the concatenation. But I see now I am merely creating an
> unnamed object. Since the object is returned by value, the scope of
> the object is no problem, but I'm still left with one puzzler:
>
> Constructors are not declared (defined? I always get those two
> mixed-up!) with a return value. If I recall correctly you are not
> supposed to use a constructor as an rvalue.

Apparently you are confused by the C++ syntax CLASSNAME(ARGS). In C++, a
typename followed by arguments in parenthesis constructs an object of
that type:

int k = 1;
double f = double(k);

This is the same for user-defined classes except that the class needs to
have a suitable constructor declared, obviously. As a side note,
constructors do not need a return type declaration, because they already
know which type they are constructing.


> (As an aside, I know that
> every constructor created with my ancient Borland C/C++ 5.xx returns
> "this". Disassembly proves it.

Disassembly is irrelevant if you are concerned with C++ language syntax.

> So have I forgotten something and this is legal code, or just
> something my compiler is allowing?

Yes, it's legal and widely used.

> If it's legal, my guess would be that I'm not returning the value of
> the constructor, but rather a copy of the temporary object the
> constructor constructed.

What you mean by "value of the constructor"?

Logically, if you return a temporary from a functions, then the temporary
is constructed in the scope of the function and then a copy of it is made
when the function return value is used somewhere. However, compilers are
pretty good optimizing away these temporaries nowadays, see

http://www.parashift.com/c++-faq/return-by-value-optimization.html

hth
Paavo

Juha Nieminen

unread,
Oct 7, 2014, 3:52:51 AM10/7/14
to
DSF <nota...@address.here> wrote:
> return FString<CH>(str1, str2);

You are not returning the "return value of the constructor", because
there's no such thing. You are instantiating an object of type FString,
constructing it, and then returning it. It's that simple.

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---
0 new messages