Legal or not?

R

Ron Natalie

Christoph Rabel said:
Base(0); // Compiles fine, but

This probably does not do what you think. This creates a temporary object of
type Base (initialized with a 0). It is not, as you might be expecting, a call
to the Base class constructor on the curent object.
Base::Base(0); // Does not compile, Comeau says:
This line isn't valid. Base::Base is not valid at all in this context.
Comeau's error message is a bit obtuse but since it's not a valid
construct it's just trying to take a stab at what it thinks you're
trying to do.

What you really want is:

Derived(int i) : Base(0) { }
 
J

Jakob Bieling

Christoph Rabel said:
Hi!

I tried to compile the following code with Comeau, but it gave me a
puzzling error(The code makes no sense, it is just to show what puzzles me)

class Base
{
public:
Base();
Base(int);
};

class Derived : public Base
{
public:
Derived(int i)
{
Base(0); // Compiles fine, but

Creates a temporary object of type 'Base'.
Base::Base(0); // Does not compile, Comeau says:

I am not sure why it said you should not take the address, because I
would have thought the line above would mean a call to the c'tor, which
cannot work.
// error: a constructor or destructor may not have its
// address taken

}
};

Is the line valid or not?

Even though I do not quite understand why Comeau prints /that/ error
message, I still think it is invalid.

hth
 
C

Christoph Rabel

Hi!

I tried to compile the following code with Comeau, but it gave me a
puzzling error(The code makes no sense, it is just to show what puzzles me)

class Base
{
public:
Base();
Base(int);
};

class Derived : public Base
{
public:
Derived(int i)
{
Base(0); // Compiles fine, but

Base::Base(0); // Does not compile, Comeau says:

// error: a constructor or destructor may not have its
// address taken

}
};

Is the line valid or not?

greets,

Christoph
 
R

Ron Natalie

Jakob Bieling said:
I am not sure why it said you should not take the address, because I
would have thought the line above would mean a call to the c'tor, which
cannot work.

Can't mean that, because constructors don't have names. Base::Base
just isn't a valid sequence here.
 
J

Jakob Bieling

Ron Natalie said:
Can't mean that, because constructors don't have names. Base::Base
just isn't a valid sequence here.


I know, but most people who write that think they can call c'tors
explicitly, which is also what it looks like: a call to that c'tor
(regardsless of the fact that this is illegal). So I would have expected the
compiler to print out something along that line.

regards
 
J

Jakob Bieling

Christoph Rabel said:
Oh, I know that. I simply was confused that I am allowed to write
Base(0); but not to write Base::Base(0);


I'd like to understand why the first line is valid and the second not. I
thought, that they are essentially "equal".


Suppose you had a typedef 'test' for 'int' inside 'Base'. Then you could
do this: Base::test (0). Now you did Base::Base (0), so you are trying to
find something inside the 'Base' namespace. But there is nothing you could
find like that; the 'Base' class is not inside the 'Base' namespace. This is
why the two lines are not equal at all.

hth
 
C

Christoph Rabel

Ron said:
This probably does not do what you think. This creates a temporary object of
type Base (initialized with a 0). It is not, as you might be expecting, a call
to the Base class constructor on the curent object.

Oh, I know that. I simply was confused that I am allowed to write
Base(0); but not to write Base::Base(0);
This line isn't valid. Base::Base is not valid at all in this context.
Comeau's error message is a bit obtuse but since it's not a valid
construct it's just trying to take a stab at what it thinks you're
trying to do.

I'd like to understand why the first line is valid and the second not. I
thought, that they are essentially "equal".

Is it because of 12.1.2, Constructors have no name and are never found
during name lookup?

thx,

Christoph
 
R

Ron Natalie

Christoph Rabel said:
Oh, I know that. I simply was confused that I am allowed to write
Base(0); but not to write Base::Base(0);

Base is a type name in this context, it's legal. Base::Base is not.
I'd like to understand why the first line is valid and the second not. I
thought, that they are essentially "equal".
Is it because of 12.1.2, Constructors have no name and are never found
during name lookup?

Paritally. The constructor doesn't have a name. Base::Base doesn't
refer to it, Base doesn't refer to it. Base works becuase it is a type
name. Base::Base is nonsense, there is no legitimate qualified identifier
of that name.
 
J

jeffc

Christoph Rabel said:
Hi!

I tried to compile the following code with Comeau, but it gave me a
puzzling error(The code makes no sense, it is just to show what puzzles me)

class Base
{
public:
Base();
Base(int);
};

class Derived : public Base
{
public:
Derived(int i)
{
Base(0); // Compiles fine, but

Base::Base(0); // Does not compile, Comeau says:

// error: a constructor or destructor may not have its
// address taken

}
};

Is the line valid or not?

I don't understand the error message, but it's just the compiler struggling
to make sense out of what you really wanted to do (as I am :) I'm sure
Base(0); isn't what you want to do either. You need to read up on
"initializer list". You need to "call" the base constructor in a special -
NOT the way you attempted.
 
J

jeffc

Christoph Rabel said:
Oh, I know that. I simply was confused that I am allowed to write
Base(0); but not to write Base::Base(0);

Because there is no "Base" defined inside the "Base".
I'd like to understand why the first line is valid and the second not. I
thought, that they are essentially "equal".

Is it because of 12.1.2, Constructors have no name and are never found
during name lookup?

No, it's because Base is in the global scope, and nowhere else. Under what
conditions would you normally use the :: operator?
 
J

jeffc

Jakob Bieling said:
I know, but most people who write that think they can call c'tors
explicitly, which is also what it looks like: a call to that c'tor
(regardsless of the fact that this is illegal). So I would have expected the
compiler to print out something along that line.

I prefer to think of it that you can call a constructor explicitly in the
initializer list. From the user's point of view (if not the compiler's),
it's indistinguishable from any other function call (someone correct me if
I'm wrong.)
 
R

Ron Natalie

jeffc said:
I prefer to think of it that you can call a constructor explicitly in the
initializer list.

You may think of it that way, but it is wrong. It is NOT calling the constructor
there and thinking that way just adds to the confusion. All you are doing is providing
initializers for the objects. Specifically, if you think that you are calling there, you might
think that the order that you specify the initializers have some meaning. Further you
can specify initializers in the list for things that don't even have constructors.
From the user's point of view (if not the compiler's),
it's indistinguishable from any other function call (someone correct me if
I'm wrong.)

I contend you are wrong. It's nothing like a function call. It's more like remembering
what the initializers are so when it's time to invoke the constructor we know what they
are.
 
C

Christoph Rabel

Jakob said:
Suppose you had a typedef 'test' for 'int' inside 'Base'. Then you could
do this: Base::test (0). Now you did Base::Base (0), so you are trying to
find something inside the 'Base' namespace. But there is nothing you could
find like that; the 'Base' class is not inside the 'Base' namespace. This is
why the two lines are not equal at all.

Doesnt this contradict 9.2:

"A classname is inserted into the scope in which it is
declared immediately after the classname is seen.
The classname is also inserted into the scope of the class
itself."

Or am I misunderstanding something here?

Christoph
 
J

jeffc

Ron Natalie said:
You may think of it that way, but it is wrong. It is NOT calling the constructor
there and thinking that way just adds to the confusion.

On the contrary, it makes initializer lists more clear to most people.
Specifically, if you think that you are calling there, you might
think that the order that you specify the initializers have some meaning.

One might, but I wouldn't. There aren't any semicolons there, so I wouldn't
think that. That's beside my point.
Further you can specify initializers in the list for things that don't
even have constructors.

Again, irrelevant and beside my point. Those things are a syntactical
convenience (just like int i(1);) and couldn't possibly be function calls.
I contend you are wrong. It's nothing like a function call. It's more like remembering
what the initializers are so when it's time to invoke the constructor we know what they
are.

"It's nothing like a function call." You can't back that one up. It's very
much like a function call. Run it through your debugger sometime and
explain to me why it doesn't act like a function call from the user's point
of view.
 
J

jeffc

Ron Natalie said:
You may think of it that way, but it is wrong. It is NOT calling the constructor
there and thinking that way just adds to the confusion. All you are doing is providing
initializers for the objects. Specifically, if you think that you are calling there, you might
think that the order that you specify the initializers have some meaning.

As further evidence that this is really a red herring, consider the
following:
int a(){return 1;}
int b(){return 2;}
int c(){return 3;}

int x = a() + b() * c();
compare with
int x = c() * b() + a();
compare with
int x = a() * b() + c();

According to your logic, you should not think of these as function calls
because then you might think that the order you specify the names has some
meaning. In both this case and the initializer list case, functions are
being called (constructors *are* special functions), and the order in which
they're called depends on something other than the sequential order in which
they appear on the page.
 
J

Jakob Bieling

Christoph Rabel said:
Doesnt this contradict 9.2:

"A classname is inserted into the scope in which it is
declared immediately after the classname is seen.
The classname is also inserted into the scope of the class
itself."

Or am I misunderstanding something here?


I do not think you misunderstood, since this does sound pretty much like
your two lines should be identical. I did not know that rule before. Now you
also made me curious as to why it does not work *g*

regards
 
R

Rob Williscroft

Christoph Rabel wrote in
Doesnt this contradict 9.2:

"A classname is inserted into the scope in which it is
declared immediately after the classname is seen.
The classname is also inserted into the scope of the class
itself."

Or am I misunderstanding something here?

It maybe that "inserted into the scope" dosen't mean becomes
a member. AFAIKT the above wording (the 2nd part) is so the
class-name is in scope in the class declaration even though
it hasn't been fully declared yet.

Rob.
 

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
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top