C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Why Does an Object of an Empty Classs Require a User-declare

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Greg Herlihy
Guest





PostPosted: Tue Sep 26, 2006 3:39 pm    Post subject: Why Does an Object of an Empty Classs Require a User-declare Reply with quote



Is there a particular reason why C++ requires that the empty class of a
const object have a user-declared, default constructor? For example,
this code will not compile:

struct Sign
{
int operator()( int i ) const
{
return -(i < 0) + (i > 0);
}
};

const Sign SignFunction; // Error: uninitialized const object

Instead, Sign must declare a default constructor:

struct Sign
{
Sign() {}

int operator()( int i ) const
{
return -(i < 0) + (i > 0);
}
};

Now, (according to a rather informal definition) a function object that
maintains no state should not declare a constructor. Especially one
whose declaration makes absolutely no difference to the program. In
contrast, declaring a const function object variable does make sense.
In fact it is not possible to define a function object in a shared
header file unless it is declared const. A non-const object definition
in a shared header file would violate the One Definition Rule (ODR).
And the gist of these observations is simply that the error illustrated
in the sample code above is not contrived, or even all that unlikely,
in light of these factors.

Now my usual response to an error compiling is to fix the error. But
there are two problems that I have with this particular compiler error
- first I don't see any error. Specifically, I don't see anything in
Sign that needs to be initialized. So I have trouble identifying
exactly what unitialized object the compiler is complaining about.
Almost as baffling to me, is the whereabouts of the
implictly-generated, default constructor that the compiiler is supposed
to generate - the one used to construct non-const Sign objects. Did it
disappear? As far as I can tell, the compiler-generated should still
exist - but for some inscrutable reason the Standard has its
invisibility prevent it from being called for a non-const instance.

The other issue that I have is that I can't that the change that fixes
this problem is any kind of change at all. How does the user declaring
the same constructor that would have been generated had the constructor
not been declared - do anything to fix this problem? As far as i can
tell, nothing should have been affected by such a change, yet somehow
the problem gets fixed.

I guess I have a third problem as well. And that is a problem of
perception: C++ seems to me to to be unique among computing languages.
In particular, it is the only language in which successfully compiling
a program may require that the programmer make a pointless change to
fix a problem that did not exist in the first place.

Greg

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Gennaro Prota
Guest





PostPosted: Tue Sep 26, 2006 8:24 pm    Post subject: Re: Why Does an Object of an Empty Classs Require a User-dec Reply with quote



On Tue, 26 Sep 2006 09:39:04 CST, "Greg Herlihy" <greghe (AT) pacbell (DOT) net>
wrote:

Quote:
Is there a particular reason why C++ requires that the empty class of a
const object have a user-declared, default constructor? For example,
this code will not compile:

struct Sign
{
int operator()( int i ) const
{
return -(i < 0) + (i > 0);
}
};

const Sign SignFunction; // Error: uninitialized const object

Instead, Sign must declare a default constructor:

It doesn't need to. You may just provide an initializer for the const
instance:

const Sign SignFunction = {};

I guess this problem was "popularized" by Scott Meyer's null (same
problem there: either you gave it a default constructor or provided an
initializer)

--
Gennaro Prota

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
kanze
Guest





PostPosted: Wed Sep 27, 2006 3:38 pm    Post subject: Re: Why Does an Object of an Empty Classs Require a User-dec Reply with quote



Gennaro Prota wrote:
Quote:
On Tue, 26 Sep 2006 09:39:04 CST, "Greg Herlihy" <greghe (AT) pacbell (DOT) net
wrote:

Is there a particular reason why C++ requires that the empty
class of a const object have a user-declared, default
constructor? For example, this code will not compile:

struct Sign
{
int operator()( int i ) const
{
return -(i < 0) + (i > 0);
}
};

const Sign SignFunction; // Error: uninitialized const object

Instead, Sign must declare a default constructor:

It doesn't need to. You may just provide an initializer for the const
instance:

const Sign SignFunction = {};

But you've missed his point: you need a user specified
initialization in order to initialize nothing.

I suspect that when the rule was written, the authors intent was
to prevent you from declaring uninitialized C-style structs. If
I have a typical C style struct, I have to provide
initialization (using the braces) if the object is const. (This
would explain, for example, why the compiler doesn't take into
account the compiler generated default constructor.) If I
provide an explicit constructor, of course, the langage supposes
that that constructor does the right thing, and that there is no
problem.

I agree with Greg that this should probably be fixed. I can see
two simple fixes:

-- In §8.5/9, change "if the object is of const-qualified type,
the underlying class type shall have a user-declared default
constructor." to "if the object is of const-qualified type,
and contains one or more non-static data members, the
underlying class type shall have a user-declared default
constructor."

-- Or more simply, drop the above clause completely. After
all, if the intent is mainly to require that C style const
objects be initialized, C doesn't have the rule, and it is,
in fact, not a rare practice to declare such a const object
in C, to have an initialize for auto objects, e.g.:
struct S { int i ; int j ; } ;
S const sInit ;

void
f()
{
S someS = sInit ;
// ...
}
The idea being to simulate for auto objects the same
initialization we get for static objects.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
SuperKoko
Guest





PostPosted: Wed Sep 27, 2006 6:15 pm    Post subject: Re: Why Does an Object of an Empty Classs Require a User-dec Reply with quote

kanze wrote:
Quote:
-- Or more simply, drop the above clause completely. After
all, if the intent is mainly to require that C style const
objects be initialized, C doesn't have the rule,
C does require initializers for const objects! and it is,
in fact, not a rare practice to declare such a const object
in C, to have an initialize for auto objects, e.g.:
struct S { int i ; int j ; } ;
S const sInit ;

void
f()
{
S someS = sInit ;
// ...
}

The code snippet below is flawed because "S const sInit;" is a
declaration of an external const object while it's an ill-formed
definition in C++ (because const variables with namespace scope are
"static" by default in C++ but not in C).
Replace "S const sInit;" with "static S const sInit;" and you'll see.
Or simply compile your code and have a look at "undefined symbol"
linker errors.

Quote:
The idea being to simulate for auto objects the same
initialization we get for static objects.

But in that case, the correct *definition* for sInit is:

struct S const sInit={0};

Seriously, I don't see any benefit (e.g. it is not more convenient nor
more simple) in specifying that an empty class can be initialized in
such way.
It breaks the easy to remember (but not exhaustive) rule that const
aggregates require aggregate initializers.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
kanze
Guest





PostPosted: Thu Sep 28, 2006 4:03 pm    Post subject: Re: Why Does an Object of an Empty Classs Require a User-dec Reply with quote

SuperKoko wrote:
Quote:
kanze wrote:
-- Or more simply, drop the above clause completely. After
all, if the intent is mainly to require that C style const
objects be initialized, C doesn't have the rule,

C does require initializers for const objects! and it is,

Where. I couldn't find it in my copy of C99. And gcc doesn't
require it.

Quote:
in fact, not a rare practice to declare such a const object
in C, to have an initialize for auto objects, e.g.:
struct S { int i ; int j ; } ;
S const sInit ;

void
f()
{
S someS = sInit ;
// ...
}

The code snippet below is flawed because "S const sInit;" is a
declaration of an external const object while it's an
ill-formed definition in C++ (because const variables with
namespace scope are "static" by default in C++ but not in C).

It's illegal in C++, because there is no initializer for sInit.
It is quite common practice in C. Except, of course, that I
miscopied from my C++ source, rather than the C source; in C, I
would have to write:

struct S const sInit ;

It's true that there are several differences here between C and
C++: to begin with, as you say, in C++, the name sInit has
internal linkage, where as in C, it has external. And while it
is a definition in both languages (the const plays no role
here), the way C and C++ define external linkage is slightly
different.

Quote:
Replace "S const sInit;" with "static S const sInit;" and
you'll see.

See what? It doesn't change anything fundamental.

Quote:
Or simply compile your code and have a look at
"undefined symbol" linker errors.

There aren't any. There's no doubt that what I have written is
a definition, and is sufficient. (I might add that gcc accepts
it---that's the only C compiler I currently have access to.)

Quote:
The idea being to simulate for auto objects the same
initialization we get for static objects.

But in that case, the correct *definition* for sInit is:
struct S const sInit={0};

That will also work, but it wasn't the idiomatic form when I was
using C. (Admittedly, we didn't have the const back then,
either, so it was simply "struct S sInit;". But adding the
const, now that it has been added to C, is a logical
progression, and it works fine with gcc.)

Quote:
Seriously, I don't see any benefit (e.g. it is not more
convenient nor more simple) in specifying that an empty class
can be initialized in such way.

Supporting existing practice in C. Personally, it doesn't make
much difference to me today, because about the only time I use
an aggregate class is because I want to be able to use the {...}
initialization. If we want to pretend that C++ POD are in some
way compatible with C objects, then not having the rule makes
sense. But I'll admit that's the only justification for using
it rather than my first suggestion (only requiring
initialization if there is one or more non-static data members).

Quote:
It breaks the easy to remember (but not exhaustive) rule that
const aggregates require aggregate initializers.

Yes, but...

When writing C++ code, you don't have aggragate types except in
order to use the {...} initialization; the simply problem
doesn't occur. So the rule doesn't jurt, but it isn't
necessary.

When trying to compile C code with a C++ compiler, on the other
hand, it makes one less thing you might have to change.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Gennaro Prota
Guest





PostPosted: Thu Sep 28, 2006 7:41 pm    Post subject: Re: Why Does an Object of an Empty Classs Require a User-dec Reply with quote

On Wed, 27 Sep 2006 09:38:30 CST, "kanze" <kanze@gabi-soft.fr> wrote:

Quote:
const Sign SignFunction; // Error: uninitialized const object

Instead, Sign must declare a default constructor:

It doesn't need to. You may just provide an initializer for the const
instance:

const Sign SignFunction = {};

But you've missed his point: you need a user specified
initialization in order to initialize nothing.

No no, I didn't miss it Smile I was just replying to the "you must
declare a default constructor part". I agree that this should be fixed
(though admittedly it's not a big problem), and from what I remember,
the "why should I specify an initialization to initialize nothing" was
exactly the point raised by Scott Meyers. In Scott's code, by the way,
the class was unnamed so defining a user constructor wasn't quite a
choice :-)

--
Gennaro Prota

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.