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

Question regarding copy constructor

165 views
Skip to first unread message

somenath

unread,
Oct 21, 2013, 12:15:23 AM10/21/13
to
I have one question regarding the output of the following program.

#include<iostream>
using namespace std;

class A {
public:
A(int x) {
cout<<"Inside constructor A "<<endl;

}
A(const A&a) {
cout<<"Inside copy constructor";
}
void operator =( int x) {
cout<<"Inside assignment operator overloading "<<endl;
}
};
int main(void)
{
A a(2);
A a1 = 2;
A a2 = a;
return 0;
}
Output
+++++++++
Inside constructor A
Inside constructor A
Inside copy constructor

For this code
A a1 = 2;
I was expecting the copy constructor would be called. Because my understanding is compiler will create a temporary object using 2 and then that temporary object will be copied to a1 object. Something as follows.
__tempObj(2);
A a1 = __tempObj;
But that is not happening here . The copy constructor is not getting called. Where am I going wrong?
How the compiler then assigning 2 to object a1?

Alf P. Steinbach

unread,
Oct 21, 2013, 12:37:04 AM10/21/13
to
On 21.10.2013 06:15, somenath wrote:
> The copy constructor is not getting called. Where am I going wrong?

No matter what a copy constructor does, the compiler is allowed to
assume, for purposes of optimization, that it does nothing but copying
the object, and that it does that perfectly.

The copy constructor is the only such special case, where the compiler
can just disregard the actual code and assume a perfect implementation.

Thus, when you have a declaration like

A a = 2;

then the formal meaning is

A a( A( 2 ) );

that is, a copy construction.

But while that means that the copy constructor must be ACCESSIBLE, the
compiler is allowed to optimize this to

A a( 2 );

that is, a direct initialization, even if that fails to produce some
intended side effect in the copy constructor.

You can find the formal rules for such COPY ELISION in C++11 �12.8/31.


Cheersw & hth.,

- Alf

K. Frank

unread,
Oct 21, 2013, 8:49:37 AM10/21/13
to
Hi Alf!

On Monday, October 21, 2013 12:37:04 AM UTC-4, Alf P. Steinbach wrote:
> On 21.10.2013 06:15, somenath wrote:
>
> > The copy constructor is not getting called. Where am I going wrong?
> ...
> Thus, when you have a declaration like
>
> A a = 2;
>
> then the formal meaning is
>
> A a( A( 2 ) );
>
> that is, a copy construction.
>
> But while that means that the copy constructor must be ACCESSIBLE, the
> compiler is allowed to optimize this to
>
> A a( 2 );
>
> that is, a direct initialization, even if that fails to produce some
> intended side effect in the copy constructor.

I agree that this is the case, but I've often
wondered why.

Given that in somenath's example, the constructor
A(int) exists, and given that the compiler is
allowed to copy-elide the copy constructor away,
why does the standard _not_ define

A a = 2;

and

A a(2);

to be synonymous? That is, why not just define
A a = 2 to be direct initialization, and be done
with it?

Given that the programmer cannot rely on the copy
constructor getting called in this situation, I
don't see any reason why letting the compiler
first construct and then copy construct would be
advantage. Wouldn't it be simpler and better (and
fully backward compatible) just to require A a = 2
to be direct initialization?

Just wondering ...

> ...
> Cheersw & hth.,
>
> - Alf


Thanks.


K. Frank

Tobias Müller

unread,
Oct 21, 2013, 11:55:47 AM10/21/13
to
"K. Frank" <kfran...@gmail.com> wrote:
[...]
> Given that in somenath's example, the constructor
> A(int) exists, and given that the compiler is
> allowed to copy-elide the copy constructor away,
> why does the standard _not_ define
>
> A a = 2;
>
> and
>
> A a(2);
>
> to be synonymous? That is, why not just define
> A a = 2 to be direct initialization, and be done
> with it?
>
> Given that the programmer cannot rely on the copy
> constructor getting called in this situation, I
> don't see any reason why letting the compiler
> first construct and then copy construct would be
> advantage. Wouldn't it be simpler and better (and
> fully backward compatible) just to require A a = 2
> to be direct initialization?

Even more so as it is already a special case. Regarding only the syntax,
you would expect the appropriate assignment operator to be called.

Tobi

Öö Tiib

unread,
Oct 21, 2013, 1:58:31 PM10/21/13
to
There certainly won't be assignment operators used in initialization. Most
coding standards suggest to write what you actually want 'A a(2);' and
to avoid writing "likely synonymous after optimizations" variants.

Tobias Müller

unread,
Oct 21, 2013, 2:42:58 PM10/21/13
to
Öö Tiib <oot...@hot.ee> wrote:
> On Monday, 21 October 2013 18:55:47 UTC+3, Tobias Müller wrote:
>> "K. Frank" <kfran...@gmail.com> wrote:
>>
>> [...]
>>
>>> Given that in somenath's example, the constructor
>>> A(int) exists, and given that the compiler is
>>> allowed to copy-elide the copy constructor away,
>>> why does the standard _not_ define
>>>
>>> A a = 2;
>>>
>>> and
>>>
>>> A a(2);
>>>
>>> to be synonymous? That is, why not just define
>>> A a = 2 to be direct initialization, and be done
>>> with it?
>>>
>>> Given that the programmer cannot rely on the copy
>>> constructor getting called in this situation, I
>>> don't see any reason why letting the compiler
>>> first construct and then copy construct would be
>>> advantage. Wouldn't it be simpler and better (and
>>> fully backward compatible) just to require A a = 2
>>> to be direct initialization?
>>
>> Even more so as it is already a special case. Regarding only the syntax,
>> you would expect the appropriate assignment operator to be called.
>
> There certainly won't be assignment operators used in initialization.

Yes, that's what I wanted to say. Syntactically it's an assignment, but in
the context of a declaration it is special cased to actually mean
initialization. But then, why in a such convoluted way?

> Most coding standards suggest to write what you actually want 'A a(2);' and
> to avoid writing "likely synonymous after optimizations" variants.

The above proposal would provide exactly that. Without relying on
optimizations.
But I agree, just writing the appropriate constructor is even better.

Tobi

Victor Bazarov

unread,
Oct 21, 2013, 3:38:22 PM10/21/13
to
On 10/21/2013 2:42 PM, Tobias Müller wrote:
> [..] Syntactically it's an assignment, but in
> the context of a declaration it is special cased to actually mean
> initialization. But then, why in a such convoluted way?

<shrug> Why not? This is one of C legacies. It's very likely that in a
function scope it literally meant the same machine code... And many an
older folk got used to seeing this form and keep using it. Imagine (a)
requiring to rewrite millions of lines(*) of

int a = 42;

to

int a { 42 };

and (b) force scores of thousands of C++ programmers to re-learn to use
that form from some point on... I don't think it's feasible.

>> [..]

*) I don't really know how many lines of such code exist and need to be
maintained, so might be off by a billion or two.

V
--
I do not respond to top-posted replies, please don't ask

James Kanze

unread,
Oct 22, 2013, 1:43:58 PM10/22/13
to
On Monday, 21 October 2013 19:42:58 UTC+1, Tobias Müller wrote:
> >> Even more so as it is already a special case. Regarding only the syntax,
> >> you would expect the appropriate assignment operator to be called.

> > There certainly won't be assignment operators used in initialization.

> Yes, that's what I wanted to say. Syntactically it's an assignment, but in
> the context of a declaration it is special cased to actually mean
> initialization.

Syntactically, it isn't an assignment. And assignment can only
occur as part of an expression, and the = sign there is *not*
part of any expression.

There are several character sequences that can be both operators
and punctuation, depending on context: the comma is the most
noted, but a single colon is also ambiguous in this regard.
That's obviously not an ideal situation, but it's one we have to
live with for historical reasons.

> But then, why in a such convoluted way?

> > Most coding standards suggest to write what you actually
> > want 'A a(2);' and to avoid writing "likely synonymous after
> > optimizations" variants.

I've seen coding standards suggest just the opposite. With copy
initialization, you'll never encounter C++'s most vexing parse.

--
James

Tobias Müller

unread,
Oct 22, 2013, 2:13:01 PM10/22/13
to
James Kanze <james...@gmail.com> wrote:
> On Monday, 21 October 2013 19:42:58 UTC+1, Tobias Müller wrote:
>>>> Even more so as it is already a special case. Regarding only the syntax,
>>>> you would expect the appropriate assignment operator to be called.
>
>>> There certainly won't be assignment operators used in initialization.
>
>> Yes, that's what I wanted to say. Syntactically it's an assignment, but in
>> the context of a declaration it is special cased to actually mean
>> initialization.
>
> Syntactically, it isn't an assignment. And assignment can only
> occur as part of an expression, and the = sign there is *not*
> part of any expression.

Yes I'm inprecise. It _looks_ like an assignment and is a special case in
the syntax. Better?

> There are several character sequences that can be both operators
> and punctuation, depending on context: the comma is the most
> noted, but a single colon is also ambiguous in this regard.
> That's obviously not an ideal situation, but it's one we have to
> live with for historical reasons.
>
>> But then, why in a such convoluted way?
>
>>> Most coding standards suggest to write what you actually
>>> want 'A a(2);' and to avoid writing "likely synonymous after
>>> optimizations" variants.
>
> I've seen coding standards suggest just the opposite. With copy
> initialization, you'll never encounter C++'s most vexing parse.

But that still does not explain why
A a = 2;
is interpreted as
A a(A(2));
and not just
A a(2);

Tobi

Öö Tiib

unread,
Oct 22, 2013, 5:30:21 PM10/22/13
to
On Tuesday, 22 October 2013 20:43:58 UTC+3, James Kanze wrote:
> > > want 'A a(2);' and to avoid writing "likely synonymous after
> > > optimizations" variants.
>
> I've seen coding standards suggest just the opposite. With copy
> initialization, you'll never encounter C++'s most vexing parse.

Ok, that makes perfect sense without tools that can warn about likely
most vexing parse. How often does anyone actually want to declare a
function in other function's body? I have had very close to zero
occasions of such desire. So most vexing parse is accidental usage
of useless feature and a tool that underlines it with red does
not take any rocket science to develop.

Rosario1903

unread,
Oct 23, 2013, 2:54:02 AM10/23/13
to
On Tue, 22 Oct 2013 18:13:01 +0000 (UTC), Tobias M�ller
<tro...@bluewin.ch> wrote:

>James Kanze <james...@gmail.com> wrote:
A a=2;

would be:
A::a() or don't know how they say that default constructor for A
applied on "a" with 0 arg
a=2 assign to "a" the value 2

Rosario1903

unread,
Oct 23, 2013, 2:56:21 AM10/23/13
to
^^^^^^^^^^^
constructor for A applied on "a" with 0 arg

> applied on "a" with 0 arg

>a=2 assign to "a" the value 2

with operator=

Juha Nieminen

unread,
Oct 23, 2013, 4:23:47 AM10/23/13
to
?? Tiib <oot...@hot.ee> wrote:
> There certainly won't be assignment operators used in initialization. Most
> coding standards suggest to write what you actually want 'A a(2);' and
> to avoid writing "likely synonymous after optimizations" variants.

Then you get problems like this:

struct A { ... };
struct Comparator { bool operator()(const A&, const A&) const { ... } };

std::map<A, int, Comparator> theMap(Comparator());

(Can't see what the problem is? Try calling one of the member functions
of theMap...)

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Öö Tiib

unread,
Oct 23, 2013, 4:32:06 AM10/23/13
to
On Wednesday, 23 October 2013 09:54:02 UTC+3, Rosario1903 wrote:
> On Tue, 22 Oct 2013 18:13:01 +0000 (UTC), Tobias M�ller
> <tro...@bluewin.ch> wrote:
> >But that still does not explain why
> >A a = 2;
> >is interpreted as
> >A a(A(2));
> >and not just
> >A a(2);
>
> A a=2;
>
> would be:
>
> A::a() or don't know how they say that default constructor for A
> applied on "a" with 0 arg
> a=2 assign to "a" the value 2

Are you suggesting such change? If you suggest it as change then that won't happen. Silent
change of behaviour won't be accepted into C++.

What Tobias suggests is what most C++ compilers do anyway because it is allowed. So I
also think that ... why not?

Öö Tiib

unread,
Oct 23, 2013, 4:46:16 AM10/23/13
to
On Wednesday, 23 October 2013 11:23:47 UTC+3, Juha Nieminen wrote:
> ?? Tiib <oot...@hot.ee> wrote:
> > There certainly won't be assignment operators used in initialization. Most
> > coding standards suggest to write what you actually want 'A a(2);' and
> > to avoid writing "likely synonymous after optimizations" variants.
>
> Then you get problems like this:
>
> struct A { ... };
> struct Comparator { bool operator()(const A&, const A&) const { ... } };
>
> std::map<A, int, Comparator> theMap(Comparator());

Should add double parentheses somewhere:

std::map<A, int, Comparator> theMap((Comparator()));

> (Can't see what the problem is? Try calling one of the member functions
> of theMap...)

The people who don't see it with bare eye should use -Wvexing-parse of clang.
I'm still thinking that there is powerful enemy rat in standard commission. Every
time they mess with initialisation they add more confusing and ambiguous
syntaxes. The new 'A a{2};' and 'A a = {2};' are screwed up as well.

Tobias Müller

unread,
Oct 23, 2013, 5:47:12 AM10/23/13
to
Rosario1903 <Ros...@invalid.invalid> wrote:
> On Wed, 23 Oct 2013 08:54:02 +0200, Rosario1903
> <Ros...@invalid.invalid> wrote:
>
>> On Tue, 22 Oct 2013 18:13:01 +0000 (UTC), Tobias Müller
>> <tro...@bluewin.ch> wrote:
>>
>>> James Kanze <james...@gmail.com> wrote:
>>> But that still does not explain why
>>> A a = 2;
>>> is interpreted as
>>> A a(A(2));
>>> and not just
>>> A a(2);
>>
>>> Tobi
>>
>> A a=2;
>>
>> would be:
>> A::a() or don't know how they say that default constructor for A
> ^^^^^^^^^^^
> constructor for A applied on "a" with 0 arg
>
>> applied on "a" with 0 arg
>
>> a=2 assign to "a" the value 2
>
> with operator=

We're going in circles.
Even if it looks like an assignment, it is in fact initialization. There is
no operator= involved.

I understand that this is legacy from C. What I don't understand is why
they chose copy initialization instead of direct initialization.

Tobi

Tobias Müller

unread,
Oct 23, 2013, 6:05:29 AM10/23/13
to
Juha Nieminen <nos...@thanks.invalid> wrote:
> ?? Tiib <oot...@hot.ee> wrote:
>> There certainly won't be assignment operators used in initialization. Most
>> coding standards suggest to write what you actually want 'A a(2);' and
>> to avoid writing "likely synonymous after optimizations" variants.
>
> Then you get problems like this:
>
> struct A { ... };
> struct Comparator { bool operator()(const A&, const A&) const { ... } };
>
> std::map<A, int, Comparator> theMap(Comparator());
>
> (Can't see what the problem is? Try calling one of the member functions
> of theMap...)

Actually, I can't right now. I have also no compiler at hand.

But I don't see how it would be relevant either. I was not proposing a
macro-like (text based) expansion from:
A a = 2;
To:
A a(2);

The second form would never occur in the source and wouldn't have to be
parsed.
What I proposed was to interpret:
A a = 2;
as:
"Call of a suitable constructor with the RHS as direct argument"

Tobi

Rosario1903

unread,
Oct 23, 2013, 11:53:20 AM10/23/13
to
On Wed, 23 Oct 2013 09:47:12 +0000 (UTC), Tobias M�ller
<tro...@bluewin.ch> wrote:

>Rosario1903 <Ros...@invalid.invalid> wrote:
>> On Wed, 23 Oct 2013 08:54:02 +0200, Rosario1903
>> <Ros...@invalid.invalid> wrote:
>>
>>> On Tue, 22 Oct 2013 18:13:01 +0000 (UTC), Tobias M�ller
>>> <tro...@bluewin.ch> wrote:
>>>
>>>> James Kanze <james...@gmail.com> wrote:
>>>> But that still does not explain why
>>>> A a = 2;
>>>> is interpreted as
>>>> A a(A(2));
>>>> and not just
>>>> A a(2);
>>>
>>>> Tobi
>>>
>>> A a=2;
>>>
>>> would be:
>>> A::a() or don't know how they say that default constructor for A
>> ^^^^^^^^^^^
>> constructor for A applied on "a" with 0 arg
>>
>>> applied on "a" with 0 arg
>>
>>> a=2 assign to "a" the value 2
>>
>> with operator=
>
>We're going in circles.
>Even if it looks like an assignment, it is in fact initialization. There is
>no operator= involved.
>
>I understand that this is legacy from C. What I don't understand is why
>they chose copy initialization instead of direct initialization.

is it so, because one *see* the same that is executed?
int a=3;
would mean reserve mem for a, and fill with 3 value
in C++=> use one constructor for a, and use operator= for copy that

if i like to use copy constructor i would use A b,a(b);
if i like to use constructor int A a(2);
if i like to use A::A() constructor and operator=(int ) A a=2
etc

but i know that all is already done, and C++ already call all i not
remember because i not study all that and i not have very very good
memory etc

>Tobi

Tobias Müller

unread,
Oct 24, 2013, 12:12:58 PM10/24/13
to
Could it be that:
B b;
A a = b;
is not actually equivalent to:
B b;
A a(A(b));
but rather to:
"Explicitly call the copy constructor of A with b as argument."
which is equivalent to:
A a(implicit_cast<const A&>(b));

This would also take conversion operators into account, not only conversion
constructors.

implicit_cast would be defined as:
template<typename A>
A implicit_cast(A a) { return a; }
or similar

Tobi

K. Frank

unread,
Oct 24, 2013, 1:40:27 PM10/24/13
to
Hello Tobi!

On Thursday, October 24, 2013 12:12:58 PM UTC-4, Tobias Müller wrote:
> "K. Frank" <> wrote:
> > Hi Alf!
> >
> > On Monday, October 21, 2013 12:37:04 AM UTC-4, Alf P. Steinbach wrote:
> >> ...
> >> Thus, when you have a declaration like
> >>
> >> A a = 2;
> >>
> >> then the formal meaning is
> >>
> >> A a( A( 2 ) );
> >>
> >> that is, a copy construction.
> >>
> >> But while that means that the copy constructor must be ACCESSIBLE, the
> >> compiler is allowed to optimize this to
> >>
> >> A a( 2 );
> >>
> >> that is, a direct initialization, even if that fails to produce some
> >> intended side effect in the copy constructor.
> > ...
> > That is, why not just define
> > A a = 2 to be direct initialization, and be done
> > with it?
> ...
> Could it be that:
>
> B b;
> A a = b;
> is not actually equivalent to:
> B b;
> A a(A(b));
> but rather to:
> "Explicitly call the copy constructor of A with b as argument."
> which is equivalent to:
> A a(implicit_cast<const A&>(b));
>
> This would also take conversion operators into account, not only conversion
> constructors.
> ...

I think you're probably right about this. (At least
it sounds good.)

Just to be clear, what I think you're saying is that
if the conversion operator:

B::operator A()

exists, but the constructor:

A::A(B)

does not, then (as currently defined)

A a = b;

will work, because the conversion operator exists,
but if we defined A a = b; to be exactly synonymous
with direct initialization, then it would fail,
because the necessary constructor doesn't exist.

Is that right?

(Perhaps I will take a look at the standard and/or
write a test program to sort this out.)

By the way, this may be relevant to the recent post
"Understanding copy construction ambiguity" on our
moderated companion group:

https://groups.google.com/forum/?fromgroups#!topic/comp.lang.c++.moderated/-5pL9ywO29Y

Perhaps somebody who understands this better than I
do could shed some light on that fellow's question.

> Tobi


Thanks.


K. Frank

Tobias Müller

unread,
Oct 24, 2013, 2:18:47 PM10/24/13
to
That's what I was thinking, though I am not a language lawyer.

> (Perhaps I will take a look at the standard and/or
> write a test program to sort this out.)
>
> By the way, this may be relevant to the recent post
> "Understanding copy construction ambiguity" on our
> moderated companion group:
>
> https://groups.google.com/forum/?fromgroups#!topic/comp.lang.c++.moderated/-5pL9ywO29Y

Yeah, reading that post actually made me thinking in that direction.

> Perhaps somebody who understands this better than I
> do could shed some light on that fellow's question.

I would have to think a bit more about it.

Tobi

Alf P. Steinbach

unread,
Oct 24, 2013, 7:21:14 PM10/24/13
to
* On 24.10.2013 19:40, K. Frank wrote:
> * On Thursday, October 24, 2013 12:12:58 PM UTC-4, Tobias Müller wrote:
>>
>> Could it be that:
>>
>> B b;
>> A a = b;
>> is not actually equivalent to:
>> B b;
>> A a(A(b));

Here Tobias probably meant

A a(( A(b) ));

which declares an object rather than a function (it's the so called
"most vexing parse" in action). A a(A(2)) declares an object because it
cannot be parsed as a function declaration. But A a(A(b)) can be parsed
as a function declaration, and so that's what's assumed...

I would have posted this clarification except I don't see his postings,
after he engaged in a bit of attempted character assassination when he
(I presume) felt that he lost the technical argument. Tobias: that's
what a "plink" or "plonk" means (the former is for light-weight trolls,
the sound of the troll hitting the inner surface of toilet). Google it.


>> but rather to:
>> "Explicitly call the copy constructor of A with b as argument."
>> which is equivalent to:
>> A a(implicit_cast<const A&>(b));
>>
>> This would also take conversion operators into account, not only conversion
>> constructors.
>> ...
>
> I think you're probably right about this. (At least
> it sounds good.)

Nope, the standard does not differentiate the cases like that.


> Just to be clear, what I think you're saying is that
> if the conversion operator:
>
> B::operator A()
>
> exists, but the constructor:
>
> A::A(B)
>
> does not, then (as currently defined)
>
> A a = b;
>
> will work, because the conversion operator exists,
> but if we defined A a = b; to be exactly synonymous
> with direct initialization, then it would fail,
> because the necessary constructor doesn't exist.
>
> Is that right?
>
> (Perhaps I will take a look at the standard and/or
> write a test program to sort this out.)

Always a good idea. :-)

However, g++ (and probably "therefore" also clang, which was aimed to be
a drop-in replacement) has a bug in this respect.

Visual C++ 12.0 behaves correctly, though.


> By the way, this may be relevant to the recent post
> "Understanding copy construction ambiguity" on our
> moderated companion group:
>
> https://groups.google.com/forum/?fromgroups#!topic/comp.lang.c++.moderated/-5pL9ywO29Y
>
> Perhaps somebody who understands this better than I
> do could shed some light on that fellow's question.

First, what the Holy Standard says about the case of copy construction
of an object of class type T, when the initializer is not of type T or a
type derived from T:

C++11 §8.5/15 sixth dash second subdash:
[quote]
user-defined conversion sequences that can convert from the source type
to the destination type or (when a conversion function is used) to a
derived class thereof are enumerated as described in 13.3.1.4, and the
best one is chosen through overload resolution (13.3). If the conversion
cannot be done or is ambiguous, the initialization is ill-formed. The
function selected is called with the initializer expression as its
argument; if the function is a constructor, the call initializes a
temporary of the cv-unqualified version of the destination type. The
temporary is a prvalue. The result of the call (which is the temporary
for the constructor case) is then used to direct-initialize, according
to the rules above, the object that is the destination of the
copy-initialization. In certain cases, an implementation is permitted to
eliminate the copying inherent in this direct-initialization by
constructing the intermediate result directly into the object being
initialized; see 12.2, 12.8.
[/quote]

The "then used to direct-initialize" means A a(( A(initializer) )).

Now re the clc++m question, the OP is being misled by a faulty compiler.
As you can see above, it's not the case that copy initialization
considers only a restricted set of conversion (which is what the OP's
compiler does). And happily, Visual C++ diagnoses both cases as
ambiguous, so that we can see that compilers disagree (it's much worse
when all available compilers agree on incorrect behavior).


Cheers & hth.,

- Alf

James Kanze

unread,
Oct 25, 2013, 10:41:00 AM10/25/13
to
On Tuesday, 22 October 2013 22:30:21 UTC+1, Öö Tiib wrote:
> On Tuesday, 22 October 2013 20:43:58 UTC+3, James Kanze wrote:
> > > > want 'A a(2);' and to avoid writing "likely synonymous after
> > > > optimizations" variants.

> > I've seen coding standards suggest just the opposite. With copy
> > initialization, you'll never encounter C++'s most vexing parse.

> Ok, that makes perfect sense without tools that can warn about likely
> most vexing parse. How often does anyone actually want to declare a
> function in other function's body?

The most vexing parse doesn't only occur within a function body.
The exact same problems occur at namespace scope. The only
difference is that often, at namespace scope, we want the
declaration to be considered a function declaration. But when
we don't, all of the same issues raise their head.

> I have had very close to zero
> occasions of such desire. So most vexing parse is accidental usage
> of useless feature and a tool that underlines it with red does
> not take any rocket science to develop.

But it should probably only do so in block scope, because
function declarations at namespace scope _are_ frequent.

--
James

Öö Tiib

unread,
Oct 25, 2013, 2:13:26 PM10/25/13
to
On Friday, 25 October 2013 17:41:00 UTC+3, James Kanze wrote:
> On Tuesday, 22 October 2013 22:30:21 UTC+1, Öö Tiib wrote:
> > On Tuesday, 22 October 2013 20:43:58 UTC+3, James Kanze wrote:
> > > > > want 'A a(2);' and to avoid writing "likely synonymous after
> > > > > optimizations" variants.
>
> > > I've seen coding standards suggest just the opposite. With copy
> > > initialization, you'll never encounter C++'s most vexing parse.
>
> > Ok, that makes perfect sense without tools that can warn about likely
> > most vexing parse. How often does anyone actually want to declare a
> > function in other function's body?
>
> The most vexing parse doesn't only occur within a function body.
> The exact same problems occur at namespace scope. The only
> difference is that often, at namespace scope, we want the
> declaration to be considered a function declaration. But when
> we don't, all of the same issues raise their head.

You are correct of course that it is not always clear what "we" want. Some
people may want lot of namespace level variables. I need them next to
none and suspect that those more hurt than aid. -Wvexing-parse of clang
works well enough for me.

> > I have had very close to zero
> > occasions of such desire. So most vexing parse is accidental usage
> > of useless feature and a tool that underlines it with red does
> > not take any rocket science to develop.
>
> But it should probably only do so in block scope, because
> function declarations at namespace scope _are_ frequent.

I also think so. Namespace scope is fortunately less hard to differentiate
from function scope than for example a type from a variable.
0 new messages