static array initialization and private copy ctor

J

John Salmon

g++ complains about illegal access to a private member
when the following is compiled with a private copy
constructor for the class C. When the copy constructor
is public, the program runs and demonstrates(?) that
the copy constructor is never called (at least no sign
of its chatter on std::cout is visible).

So - is it necessary to have a public copy constructor
in order to use "function style" initializers for an
array of objects? Or is this a bug in g++?

[jsalmon@river c++]$ cat arrayinitializer.cpp
#include <iostream>

struct C{
int i;

C(int i_) : i(i_){
std::cout << "integer ctor(" << i << ") invoked\n";
}

// Making the copy constructor private gets complaints
// from gcc:
// staticinitializer.cpp:17: error: 'C::C(const C&)' is private
// staticinitializer.cpp:25: error: within this context
// But leaving it public demonstrates(?) that it
// is never called. The integer ctor is used, so why the complaint?
#ifdef PRIVATE_COPY_CTOR
private:
#endif
C(const C& from) : i(from.i) {
std::cout << "copy ctor(" << from.i << ") invoked\n";
}

};

static C arr[] = {C(11), // integer ctor
C(3), // integer ctor
C(5)}; // integer ctor

int main(int argc, char **argv){
return 0;}
[jsalmon@river c++]$ g++ arrayinitializer.cpp
[jsalmon@river c++]$ a.out
integer ctor(11) invoked
integer ctor(3) invoked
integer ctor(5) invoked
[jsalmon@river c++]$ g++ -DPRIVATE_COPY_CTOR arrayinitializer.cpp
arrayinitializer.cpp:19: error: `C::C(const C&)' is private
arrayinitializer.cpp:27: error: within this context
arrayinitializer.cpp:19: error: `C::C(const C&)' is private
arrayinitializer.cpp:27: error: within this context
arrayinitializer.cpp:19: error: `C::C(const C&)' is private
arrayinitializer.cpp:27: error: within this context
[jsalmon@river c++]$
 
V

Victor Bazarov

John said:
g++ complains about illegal access to a private member
when the following is compiled with a private copy
constructor for the class C. When the copy constructor
is public, the program runs and demonstrates(?) that
the copy constructor is never called (at least no sign
of its chatter on std::cout is visible).

So - is it necessary to have a public copy constructor
in order to use "function style" initializers for an
array of objects? Or is this a bug in g++?

[jsalmon@river c++]$ cat arrayinitializer.cpp
#include <iostream>

struct C{
int i;

C(int i_) : i(i_){
std::cout << "integer ctor(" << i << ") invoked\n";
}

// Making the copy constructor private gets complaints
// from gcc:
// staticinitializer.cpp:17: error: 'C::C(const C&)' is private
// staticinitializer.cpp:25: error: within this context
// But leaving it public demonstrates(?) that it
// is never called. The integer ctor is used, so why the
complaint? #ifdef PRIVATE_COPY_CTOR
private:
#endif
C(const C& from) : i(from.i) {
std::cout << "copy ctor(" << from.i << ") invoked\n";
}

};

static C arr[] = {C(11), // integer ctor
C(3), // integer ctor
C(5)}; // integer ctor

int main(int argc, char **argv){
return 0;}
[..]

You should probably try online test drive of Comeau C++ to verify
whether certain things are valid/legal. It's not completely bug-
free, but it's damn close.

In your case, yes, you need an *accessible* copy-constructor to
initialise that array unless it is declared a member of the same
class. The simpler way to see what you're doing is

C val = 666;

or

C val(C(666));

V
 
I

Ivan Novick

John said:
g++ complains about illegal access to a private member
when the following is compiled with a private copy
constructor for the class C. When the copy constructor
is public, the program runs and demonstrates(?) that
the copy constructor is never called (at least no sign
of its chatter on std::cout is visible).
I think its a good question. Here is simplified code. When you run
it, the copy constructor never prints out, indicating it is never
called, but when you make the copy constructor private, the code
doesn't compile. Any one else out there know why g++ is complaining
about a private copy constructor even when it appears never to call it?

#include <iostream>

struct C{
int i;

C(int i_) : i(i_)
{
}

C(const C& from) : i(from.i)
{
std::cout << "IT IS USED" << std::endl;
}

};

int main(int argc, char** argv)
{
C a = 1;
return 0;
}
 
V

Victor Bazarov

Ivan said:
John said:
[..] Here is simplified code. When you run
it, the copy constructor never prints out, indicating it is never
called, but when you make the copy constructor private, the code
doesn't compile. Any one else out there know why g++ is complaining
about a private copy constructor even when it appears never to call
it?

The short answer is "because C++ Standard requires so". Any compiler
that wants to be considered compliant would do that, g++ included.
Not calling an available copy constructor is called optimisation which
may or may not occur (and is also explicitly allowed in the Standard).
However, the initialisation syntax in the original message is called
copy-initialisation, and it requires an *accessible* copy constructor.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top