const object declaration

  • Thread starter subramanian100in
  • Start date
S

subramanian100in

Consider the following program:

#include <iostream>

using namespace std;

class X
{
public:
int value() const { return val; }
int val;
};

int main()
{
const X obj;

return 0;
}

When this program is compiled with g++ as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp

the following compilation error is generated for the line const X obj;

error: uninitialized const `obj'

However VC++ 2005 Express Edition gives only the following warning(no
error):

warning: 'obj' : 'const' automatic data initialized with compiler
generated default constructor produces unreliable results

Which is the correct behaviour as per the standard ?

Kindly clarify.

Also please let me know how to set the compilation flags in VC++ 2005
Express Edition IDE similar to the command line g++ compilation flags
as mentioned above.

Thanks
V.Subramanian
 
B

benben

Which is the correct behaviour as per the standard ?

I don't know. But my bet is if you define an empty constructor your
problem should go away.
Kindly clarify.

Also please let me know how to set the compilation flags in VC++ 2005
Express Edition IDE similar to the command line g++ compilation flags
as mentioned above.

That, im afraid, is better asked in the gcc group.

Ben
 
V

Victor Bazarov

benben said:
[..]
Also please let me know how to set the compilation flags in VC++ 2005
Express Edition IDE similar to the command line g++ compilation flags
as mentioned above.

That, im afraid, is better asked in the gcc group.

Or in the VC++ newsgroup.

V
 
A

Abhishek Padmanabh

benben said:
[..]
Also please let me know how to set the compilation flags in VC++ 2005
Express Edition IDE similar to the command line g++ compilation flags
as mentioned above.
That, im afraid, is better asked in the gcc group.

Or in the VC++ newsgroup.

V

I asked this once on clc++m and had not got a convincing answer. It is
mandated by the standard that a user-defined constructor must be
provided. It is needed even though there are no members in the class.
It just is as it is. I am not aware of the rationale behind this
though.

In case the class has a POD type, it would remain uninitialized
(indeterminate value) when default constructor (by the compiler
generated default constructor). In case of non-POD members, they would
have been default initialized. An indeterminate POD type's value is
rather useless but for non-POD types, it might make sense. I don't
know about the rationale but may be it is based on something along
these lines, to avoid complexity. I don't know for sure. May be some
guru will enlighten us! :)
 
V

Victor Bazarov

Abhishek said:
benben said:
[..]
Also please let me know how to set the compilation flags in VC++
2005 Express Edition IDE similar to the command line g++
compilation flags as mentioned above.
That, im afraid, is better asked in the gcc group.

Or in the VC++ newsgroup.

V

I asked this once on clc++m and had not got a convincing answer. [..]

As you may have noticed, I removed all mention of the C++ problem but
left in the "compilation flags" request. That (and only that) is what
I am suggesting asking about in the VC++ newsgroup.

V
 
A

Abhishek Padmanabh

Abhishek said:
benben wrote:
[..]
Also please let me know how to set the compilation flags in VC++
2005 Express Edition IDE similar to the command line g++
compilation flags as mentioned above.
That, im afraid, is better asked in the gcc group.
Or in the VC++ newsgroup.
I asked this once on clc++m and had not got a convincing answer. [..]

As you may have noticed, I removed all mention of the C++ problem but
left in the "compilation flags" request. That (and only that) is what
I am suggesting asking about in the VC++ newsgroup.

Sorry about that! I wrongly quoted your response. My reply was to the
original post. I wouldn't have said : "May be some
guru will enlighten us! :)" to you! :)
 
V

Victor Bazarov

Abhishek said:
[..] I wouldn't have said : "May be some
guru will enlighten us! :)" to you! :)

Hey, why not? I'll gladly take a guru's advice. After all it's not
that often gurus grace us with their presence here...

V
 
B

Bo Persson

Abhishek Padmanabh wrote:
:: On Dec 3, 7:54 pm, "Victor Bazarov" <[email protected]>
:: wrote:
::: benben wrote:
::::: [..]
::::: Also please let me know how to set the compilation flags in
::::: VC++ 2005 Express Edition IDE similar to the command line g++
::::: compilation flags as mentioned above.
:::
:::: That, im afraid, is better asked in the gcc group.
:::
::: Or in the VC++ newsgroup.
:::
::: V
::
:: I asked this once on clc++m and had not got a convincing answer.
:: It is mandated by the standard that a user-defined constructor
:: must be provided. It is needed even though there are no members in
:: the class. It just is as it is. I am not aware of the rationale
:: behind this though.
::
:: In case the class has a POD type, it would remain uninitialized
:: (indeterminate value) when default constructor (by the compiler
:: generated default constructor). In case of non-POD members, they
:: would have been default initialized. An indeterminate POD type's
:: value is rather useless but for non-POD types, it might make
:: sense. I don't know about the rationale but may be it is based on
:: something along these lines, to avoid complexity. I don't know for
:: sure. May be some guru will enlighten us! :)

Since no guru appeared, I will try to answer this. :)

The reason for PODs to be different, is that they behave like they do
in C. Had C++ added initialization to types that C does not, it would
have

1) changed old behaviour of existing code
and
2) lost all benchmarks to C code.


Bo Persson
 
J

James Kanze

Consider the following program:
#include <iostream>
using namespace std;
class X
{
public:
int value() const { return val; }
int val;
};

int main()
{
const X obj;

return 0;
}
When this program is compiled with g++ as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp
the following compilation error is generated for the line const X obj;
error: uninitialized const `obj'
However VC++ 2005 Express Edition gives only the following warning(no
error):
warning: 'obj' : 'const' automatic data initialized with compiler
generated default constructor produces unreliable results
Which is the correct behaviour as per the standard ?
Both.

Kindly clarify.

The standard says that it is an error, requiring a diagnostic.
Both compilers have issued a diagnostic. The standard also says
that once the diagnostic has been issued, the compiler is free
to do whatever it wants.

Technically, the standard also says that the compiler is
required to document what it considers a diagnostic in such
cases. G++ more or less says "any output from the compiler".
I've not found where VC++ documents this, but if it does so like
g++, then anytime you compile without /nologo, the compiler has
issued the diagnostic. And while the standard requires
diagnostics in certain cases, it never forbids them.
Also please let me know how to set the compilation flags in
VC++ 2005 Express Edition IDE similar to the command line g++
compilation flags as mentioned above.

You'll have to ask in a VC++ group for that, I suspect. In all
likelihood, of course, there won't be an exact equivalent (there
never is); you'll have to specify what you want, and someone
will probably give you the corresponding flags.
 
J

James Kanze

I asked this once on clc++m and had not got a convincing
answer. It is mandated by the standard that a user-defined
constructor must be provided.

No it isn't. It is mandated that there be some non-trivial
initialization. In his case, something like:

X const obj = { 1 } ;

would be legal, for example.
It is needed even though there are no members in the class.
It just is as it is. I am not aware of the rationale behind
this though.

The requirement in the case of no data members is probably just
the result of an oversight. Since it's trivial to add a no-op
default constructor, however, it's no big problem.
In case the class has a POD type, it would remain
uninitialized (indeterminate value) when default constructor
(by the compiler generated default constructor).

In the case we're considering, the class is a POD.
 
S

subramanian100in

The following program DOES NOT COMPILE as mentioned earlier in the
beginning of the thread

#include <iostream>

using namespace std;

class X
{
public:
int val;
};

int main()
{
const X obj;

return 0;

}

However the following program COMPILES fine.

#include <iostream>

using namespace std;

class Test
{
public:
Test() { cout << "Test() default ctor" << endl; }
};

class X
{
public:
Test obj;
int val;
};

int main()
{
const X obj;

return 0;
}


I am unable to understand why this program compiles well and the
previous program does not compile.

Kindly explain.

Thanks
V.Subramanian
 
J

James Kanze

The following program DOES NOT COMPILE as mentioned earlier in the
beginning of the thread
#include <iostream>
using namespace std;
class X
{
public:
int val;
};

int main()
{
const X obj;

return 0;
}
However the following program COMPILES fine.
#include <iostream>
using namespace std;
class Test
{
public:
Test() { cout << "Test() default ctor" << endl; }
};

class X
{
public:
Test obj;
int val;
};
int main()
{
const X obj;

return 0;
}
I am unable to understand why this program compiles well and the
previous program does not compile.

I was about to say: because in the first example, the default
constructor is trivial (so an initialization is required),
whereas in the second it is not. On re-reading the standard,
however... in §8.5/9, it says "If no initializer is specified
for an object, and the object is of (possibly cv-qualified)
non-POD class type (or array thereof), the object shall be
default-initialized; if the object is of const-qualified type,
the underlying class type shall have a user-declared default
constructor." According to this, since X does not have a
user-declared default constructor, it shouldn't compile. But it
does, with all three of the compilers at my disposition (g++,
Sun CC and VC++).

I'll admit that this somewhat surprises me. I had always
thought (and apparently, the compilers agree with me) that the
rule was that the class must have a non-trivial default
constructor. Since the (compiler generated) default constructor
for X in the second example is non-trivial, the code would be
OK. Given that three compilers also disagree with what I've
just quoted in the standard, I wonder, too, if there isn't
something else that I've missed.

Thinking about it, I think what the rule should be is: an
initializer is required if the class has no user defined
default constructor, and has one or more sub-objects which have
trivial default constructors. That would allow const instances
without initializers for things like:

struct A
{
virtual void f() ;
} ;

or

struct B
{
std::vector< int > v ;
} ;

. In both cases, all fields are sufficiently initialized (and
it was to allow such things that I thought the rule involved
trivial vs. non-trivial default constructor). And would cause
your second example to fail to compile, since X::val has a
trivial default constructor. (It doesn't cover all cases, of
course. For example:

struct A
{
virtual void f() ; // means default ctor non-trivial.
int i ;
} ;

struct B
{
A a ;
} ;

B const b ;

would still create a const object in which A::i wasn't
initialized.)
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top