[comp.lang.c++] Some annoying questions answered, I hope

ark@alice.UUCP (Andrew Koenig) (07/20/89)

In article <42941@bbn.COM>, news@bbn.COM (News system owner ID) writes:

> 1) The report says that the const qualifier is treated rather like a #define in
>     C++ in that a declaration
> 	const int i=3;
>     with external scope does not define an external variable in C++.  After
>     fiddling a little with my C++ translator here (Designer C++) I noticed
>     that this statement is true for ints, shorts, longs, chars, unsigneds,
>     etc. but not for doubles, floats, enums, pointers, classes, arrays.

There are two separate questions.  First, is `i' given external
linkage?  That is, if I say

	const int i = 3;

in one compilation and

	extern const int i;

in another compilation, do these two declarations refer to the same
entity?  The answer is `no' -- the default for const objects is
internal linkage so you would have to say

	extern const int i = 3;

to make the two `i's the same.

The second question is whether or not any memory is allocated for `i'.
The answer is `yes, but the compiler is allowed to dispense with
allocating memory if it sees it can do so safely.'  Doing so is just
an optimization, and it is carried out in just those circumstances
when it is invisible except for its effect on storage consumption.

>    Is this discrepency fixed in version 2? (and how on earth is the compiler
>     supposed to deal with a constant class initialized by an external
>     constructor?)
>    What is supposed to happen if one takes the address of what would be in
>     ANSI c an external constant integer? (or is that illegal)

For instance:

	const int i = 7;
	const int* ip = &i;

allocates memory for `i' because it needs an address to put in `ip.'

> 2) another question about constants, suppose I have a class
> 	class number {
> 	    /* ... */
> 	public:
> 	    number(int);
> 	    operator+(number&);
> 	    operator+=(number&);
> 	};
> 	const number zero(0);
> 
> 	foo() {
> 	    number x;
> 	    zero+x;
> 	    zero += x;
> 	}
>     Now since a `this' argument has type pointer to number it should not
>     accept a constant number.  However if we say this constant objects are
>     useless.  On the other hand if we say the type of this is pointer to
>     const number then we can't write a += operator.
>    How should C++ handle constant objects?

You're correct that operator+ and operator+= as you've written
them will not accept a constant number.  However, there are several
things you can do.  For example:

	class number {
	    /* ... */
	public:
	    number(int);
	    number operator+(const number&) const;
	    number& operator+=(const number&);
	};

I've made a few changes to your declarations here.  First, by
saying `const number&' instead of `number&' as the argument of
operator+, I've allowed the right-hand operand of operator+ to be
a const number or a non-const number (because you can bind a
const number& to a number object).  The `const' after the right
parenthesis says that operator+ doesn't modify the object on which
you're calling it, so it can be called for constant objects.
I also declared a return type for operator+.

I made similar changes to operator+=, but because it modifies its
object I didn't say `const' after the ).  Thus you can use + on
a constant object but not +=.

Incidentally, I think it's better to avoid using member functions
for symmetrical operations like + and do it this way instead:

	number operator+(const number&,const number&);

Make it a friend of the number class if needed.

>     Is
> 	foo() {
> 	    /* ... */
> 	    goto L1;
> 	    /* ... */
> 	    String x(10);
> 	    L1:
> 	}
>    also illegal (again the constructor for x does not get called)

Yes.

>     Assume there is a destructor for String, then is
> 	foo() {
> 	    /* ... */
> 	    {
> 		String x(10);
> 		goto L1;
> 	    }
> 	    L1:
> 	}
>    illegal?

No, that's fine.  Goto out of a block causes destructors to be
called for objects that were constructed in that block.  Same
for break and continue.

> 4) Consider
> 	for ( i=0 ; i<10; ++i )
> 	    String j(10);
>    To my understanding this is valid C++, what is the scope of j?

This is invalid in 2.0 for exactly that reason.

> 5) The report mentions that in version 2 classes define a local scope in that
>     enums declared inside the class are only available inside the class (and
>     its members).
>    Does this extend to classes defined inside another class?
>     (if not why not)

No, sorry.  That would introduce too large an incompatibility with
C and with previous versions of C++.  It would be nice, but...

> 6) I have noticed that in Designer C++ a constructor is always public, even
>     if it isdeclared in a private part of the class (and the same is true
>     of the destructor)?

It's a bug, fixed in 2.0.
-- 
				--Andrew Koenig
				  ark@europa.att.com