A few minor questions

Q

questioner_x

I have a few questions about C++.

1. Of what use is a reference to a function? Why not just use a
pointer, which can be checked against NULL?

2. What happens when an exception occurs inside an exception?

3. Suppose I have multiple constructors for a class. One has zero
parameters, others have more. If I call one that has parameters, will
the zero-parameter version be called first?

4. Suppose I have a constructor for a subclass. The constructor of the
parent is not declared virtual. When I call the subclass constructor,
will the parent class's constructor be called first?

Thanks.
 
J

joecook

I have a few questions about C++.

1. Of what use is a reference to a function? Why not just use a
pointer, which can be checked against NULL?

By using a reference you don't even need to check for NULL.
2. What happens when an exception occurs inside an exception?

see below
3. Suppose I have multiple constructors for a class. One has zero
parameters, others have more. If I call one that has parameters, will
the zero-parameter version be called first?

see below
4. Suppose I have a constructor for a subclass. The constructor of the
parent is not declared virtual. When I call the subclass constructor,
will the parent class's constructor be called first?

Are these homework questions? Have you made any attempt to answer
them? (See the FAQ).

The questions are puzzling because you could find the answers yourself
with a very small amount of code and some print-outs.

Joe
 
A

Alf P. Steinbach

* (e-mail address removed):
I have a few questions about C++.

1. Of what use is a reference to a function? Why not just use a
pointer, which can be checked against NULL?

Why would you /want/ to have to check against 0?

References versus pointers are the same for functions as for anything else.

Pointers are generally assignable, references are not; pointers can be used when
interfacing to C code.

2. What happens when an exception occurs inside an exception?

A concrete code example, one that is complete and minimal, might help to make it
clear what the question is about.

3. Suppose I have multiple constructors for a class. One has zero
parameters, others have more. If I call one that has parameters, will
the zero-parameter version be called first?
No.


4. Suppose I have a constructor for a subclass. The constructor of the
parent is not declared virtual.

Constructors can't be declared virtual.

When I call the subclass constructor,
will the parent class's constructor be called first?

Yes.


Cheers & hth.,

- Alf
 
A

Alf P. Steinbach

* blargg:
You cannot call constructors;

Of course one can, and that's the terminology employed both in practical
programming and by the standard.

the compiler does it as a part of constructing an object.

I think you mean that the compiler generates machine code (or other executable
code such as byte code) that calls a constructor.

And that is partially correct.

A source code constructor call may however not necessarily be translated to an
actual machine code call.

When constructing an object, the compiler never
calls more than one constructor for a given class.

That's literally meaningless, but I think you mean, "the generated machine code"
rather than "the compiler".

And if so then that's very incorrect.

But a correct description of it all, including calls to base class constructors,
the case of virtual inheritance, C++0x constructor call forwarding, and the
whole shebang, would be long.

A constructor cannot be virtual, since it creates an object out of storage
where there was none before.

I'm sorry but that's again incorrect, a misguided rationalization. The reason
that a constructor cannot be declared "virtual" in C++ is because the language
is designed that way. As discussed ad nauseam before it's not at all difficult
to find reasonable and useful semantics for a virtual-declared constructor, and
indeed standard terms such as "virtual constructor" (see the FAQ) wouldn't exist
if such reasonable and practically useful semantics did not exist.

And again, you cannot call a constructor directly;

I'm sorry but that's meaningless.

the compiler does it as a part of constructing an object.

In C++98 the compiler does not call anything in the program being compiled; it
just generates corresponding code (usually machine code).

You
can supply parameters for a base class constructor, which the compiler
calls before executing the body of the derived class consturctor. "derived
class" is the C++ term for subclass, and "base class" for the parent, BTW.

I imagine the C++ FAQ might answer related questions:
<http://www.parashift.com/c++-faq-lite/>

Yes, the FAQ is a good idea. :)


Cheers & hth.,

- Alf
 
I

Ioannis Vranos

Alf said:
* blargg:

Of course one can, and that's the terminology employed both in practical
programming and by the standard.


No you can't. For example the following code will no compile:

int main()
{
class SomeClass
{
};


SomeClass obj;

obj.SomeClass();
}



I think you mean that the compiler generates machine code (or other
executable code such as byte code) that calls a constructor.

And that is partially correct.

A source code constructor call may however not necessarily be translated
to an actual machine code call.


I think you are writing replies just to look like you oppose to something, rather than provide helpful guidance.

I'm sorry but that's again incorrect, a misguided rationalization. The
reason that a constructor cannot be declared "virtual" in C++ is because
the language is designed that way. As discussed ad nauseam before it's
not at all difficult to find reasonable and useful semantics for a
virtual-declared constructor, and indeed standard terms such as "virtual
constructor" (see the FAQ) wouldn't exist if such reasonable and
practically useful semantics did not exist.


A "virtual" or "non-virtual" constructor doesn't make a lot of sense. Considering the current situation as
being "virtual" constructors the default, here is an example that shows that a "non-virtual" constructor
wouldn't make sense.


int main()
{
class BaseClass
{
public:
non-virtual BaseClass() {}
};


class DerivedClass: public BaseClass
{
};



// It doesn't make sense
DerivedClass *pDerived= new BaseClass;
}





--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
J

James Kanze

* blargg:
Of course one can, and that's the terminology employed both in
practical programming and by the standard.

Here we go again:).

You've actually hit the nail on the head this time: it's
terminology. The problem is that "to call a constructor" (when
it's the programmer who does the calling) means different things
in different contexts.

-- At the language level, there is no expression syntax to
"call a constructor" (i.e. in the way there is a "pseudo
destructor call" syntax). When someone says that "you can't
call a constructor" in C++, this is generally what they
mean---there is no expression syntax which calls a
constructor, and does nothing but call a constructor.

-- In practice, of course, constructors get called:). And
they get called because of things the programmer has
written. When someone speaks about the programmer "calling
a constructor", what they generally mean is that the
programmer has intentionally used a some construct which he
knows will result in the constructor being called (along
with, usually, the memory for the object being allocated).
Because of possible confusion, I prefer calling this
"creating an object", but the expression "call a
constructor" is certainly widely used in this sense
(including, as you point out, a couple of places in the
standard).

-- If I'm writing low level code, I may want to separate
allocation and initialization. In this case, I might speak
of "calling the constructor" as a shorthand for using a
placement new. This is really a more or less advanced
technique, however, and I don't think it is relevant to the
original poster.

I presume that the original poster was using the expression in
the second sense. In the context of his question, however, I
would avoid the expression "you call the constructor", because I
think what is important is that anytime the constructor of a
derived class is called (regardless of who does the calling or
why), the constructor of the base class is called first. The
use of the active form, "you call the constructor" might suggest
that there are cases when something else calls the constructor,
when this might not be true.
I think you mean that the compiler generates machine code (or
other executable code such as byte code) that calls a
constructor.

I think he probably means that the abstract machine in the
standard calls the constructor. What this translates to in
machine code depends on the compiler, and the degree of
optimization.
And that is partially correct.
A source code constructor call may however not necessarily be
translated to an actual machine code call.

Now I'm not sure what you're talking about. What exactly do you
mean by "a source code constructor call"? One particular
expression construct, defined in section 5? Or anything in the
source code which is defined to result in a constructor call in
the abstract machine? And is your point the fact that the
compiler may generate the constructor inline (even if it isn't
declard inline), or that it has explicit authorization to
suppress certain copies (which results in the constructor of the
copy being suppressed)? Or even a more liberal application of
the "as if" rule: if you define an object with a trivial
destructor, or whose destructor has no effect on "observable
behavior", the compiler can eliminate it, since eliminating it
has no effect on observable behavior.
That's literally meaningless, but I think you mean, "the
generated machine code" rather than "the compiler".
And if so then that's very incorrect.

Most of all, it's very incorrect. The compiler always
"constructs" each sub-object exactly once. If there are several
sub-objects of the same (class) type, then the compiler will
call the constructor of this type several times.

(For the rest, I'm interpreting "the compiler calls the
constructor" to mean: the standard specifies that the abstract
machine will call the constructor.)
But a correct description of it all, including calls to base
class constructors, the case of virtual inheritance, C++0x
constructor call forwarding, and the whole shebang, would be
long.

I think you could do in in a single page (DIN A4). It's about
the limit of the acceptable posting size, but more to the point,
anyone who asks this sort of question probably needs a lot more
information as well, and should consult a more complete
description.
I'm sorry but that's again incorrect, a misguided
rationalization. The reason that a constructor cannot be
declared "virtual" in C++ is because the language is designed
that way. As discussed ad nauseam before it's not at all
difficult to find reasonable and useful semantics for a
virtual-declared constructor, and indeed standard terms such
as "virtual constructor" (see the FAQ) wouldn't exist if such
reasonable and practically useful semantics did not exist.

Again, "virtual" can have different meanings in different
contexts. A constructor cannot be virtual in the sense of the
language standard, since the language standard defines virtual
resolution to involve the dynamic type of the existing object.
When we speak of a "virtual constructor", we are talking of
something that isn't just a constructor (in the strict sense of
the language). (Which doesn't mean that the language couldn't
have provided for it in some way.)
 
A

Alf P. Steinbach

* Ioannis Vranos:
No you can't. For example the following code will no compile:

int main()
{
class SomeClass
{
};


SomeClass obj;

obj.SomeClass();
}

You're silly: that's not a valid constructor call.



Cheers, &hth.,

- Alf
 
A

Alf P. Steinbach

* Jeff Schwab:
The standard does use that phrase, and it's popular in vernacular.
However, you really cannot call a constructor directly in C++.

Depends of course on what /you/ mean by "directly", but for an ordinary
interpretation, yes of course you can: you're doing that all the time.

There's just [no dedicated] syntax to do it.

Right in isolation: that's how it is with a lot of things in C++, there's just
no dedicated syntax.

But one wonders why you think it's a good idea to confuse people by pointing out
the lack of clean syntax as if it had some relevance to any particular item of
discussion?

I.e., even though your statement is correct in isolation, it does seem more than
a little dubious in context, like actively designed to mislead, or the result of
a confused mind.

The closest you can get [to a direct constructor call] is placement-new.

No, on the contrary, placement new is (at least potentially) very indirect.
That's because it has to handle allocator function arguments and exception
cleanup. You might think about how would you implement placement new as a
routine -- or actually try that, it's AFAIK not possible in C++98 -- and
then you'll see why this is a very indirect thing, why it's a built-in operator
instead of a library routine (namely, because of the necessary indirection).

Making this issue seem fuzzy does not help anybody.

Right, in isolation. In context this is very misleading, implying as it does
that it's not you who's making thing seem unclear, but rather everybody else.
Well, in politics it might work to accuse others of what you're doing yourself,
but this is a technical forum where such political mæeneuverings are exposed.


Cheers, & hth.,

- Alf
 
A

Alf P. Steinbach

* Jeff Schwab:
Alf said:
* Jeff Schwab:
The standard does use that phrase, and it's popular in vernacular.
However, you really cannot call a constructor directly in C++.
There's just [no dedicated] syntax to do it.

Right in isolation: that's how it is with a lot of things in C++,
there's just no dedicated syntax.

But one wonders why you think it's a good idea to confuse people by
pointing out the lack of clean syntax as if it had some relevance to
any particular item of discussion?

It's not only a lack of clean syntax. How would you directly call a
constructor? Given something like:

auto std::string s;

The constructor is called by the system on your behalf, but so is the
destructor. Saying this is a "constructor call" is no more meaningful
than saying it's a "destructor call."

Actually this is one of the cases where you absolutely need to employ the term
"constructor call" in order to understand the standard. Which uses that phrase
in this connection. And so it is very meaningful not just conceptually but also
in the formal, for without it the standard's wording becomes void of meaning.

Namely, the standard /defines/ a default constructor as one that (quoting from
memory) "can be called without arguments".

Which if you think about it implies very different things at the machine code
level and at the source code level. Which I'm mentioning just because I think
you're demonstrating enough of active confusion to think that perhaps the
standard in this case refers to machine code or even less constraining a
recursive reference without base case to the abstract machine. Well it doesn't,
neither here nor (AFAIK) anywhere else: the phrasing means that by definition
you have a default constructor if at the source code level you can call that
constructor without arguments, as you're doing above. :)

By the way, you keep claiming that my motives are to be intentionally
misleading, and you alternately accuse me of being malicious and
confused-bordering-on-insane. Do me a favor and drop the insults, OK?

Please stop accusing people of things. I'm getting tired of your ad hominem
attacks. In your previous posting it was other people, or me, intentionally
making things fuzzy, and now it's other people or me accusing you of being
malicious and bordering-on-insane. Such accusations are just counter-productive.
You are confused about a technical issue, that does not imply you're insane. :)


Cheers & hth.,

- Alf
 
A

Alf P. Steinbach

* blargg:
Jeff said:
Alf said:
* Jeff Schwab:
The standard does use that phrase, and it's popular in vernacular.
However, you really cannot call a constructor directly in C++.

There's just [no dedicated] syntax to do it.
Right in isolation: that's how it is with a lot of things in C++,
there's just no dedicated syntax.

But one wonders why you think it's a good idea to confuse people by
pointing out the lack of clean syntax as if it had some relevance to any
particular item of discussion?
It's not only a lack of clean syntax. How would you directly call a
constructor? Given something like:

auto std::string s;

The constructor is called by the system on your behalf, but so is the
destructor. Saying this is a "constructor call" is no more meaningful
than saying it's a "destructor call."

And so is space allocated and deallocated for the object. Even simply
using placement new involves extra machinery, for example if creating a
Derived object and the Derived constructor throws, the compiler will then
call the Base destructor, then placement delete. That's a lot more than
simply calling the constructor,

A placement new invocation is a little more than a direct constructor call, yes,
as I've already pointed out in this thread (not to mention countless earlier
threads); it might resonably be described as an indirect constructor call.

But as I pointed out in the article you're replying to, but misleadingly snipped
by you, where instead you misleadingly chose to discuss a different example, for
the particular example chosen by Jeff above, the standard, not surprisingly,
refers to the source code as a constructor call.

So what you write above is true in isolation, but misleading in context because
it's not relevant but the context makes it appear to be somehow relevant.

Summing up, what you write above is nothing more than misdirection.

And since I think you know that, I therefore think you're actively trying to
make others believe something that you yourself know is false, i.e. I think that
the above fits any reasonable definition of lying.

and a clear case that the constructor is
not a normal function at all.

Yes, a constructor is, according to the standard, a special member function.

Special member functions are special.

But really, there can't many, if any at all, who have failed to grasp that
"special" means "special", so it's sort of unnecessary to point it out unless
the intent is to confuse and muddle some issue.

Good luck.

That ad hominem attack is at the level of a preschool child throwing a tantrum.

When you are mistaken about something, and someone helps you out, you shouldn't
thank that person by throwing veiled insinuations about.

Since you're (1) lying, as shown above, at least in my opinion, and (2) throwing
ad hominem attacks, I don't see any reason to continue this discussion, except
nailing you again if you persist with more of that kind.


Cheers,

- Alf
 
Q

Questioner

An exception is an object, not an unit of execution, so this makes no
sense.

Sounds good, I was going to try to code an exception within an
exception
but then I tried this in Cygwin:

try {
int *a = 0;
*a = 0;
}
catch ( ... ) {
cout << "uh oh\n";
}

And got:

5 [main] a 2980 _cygtls::handle_exceptions: Error while dumping
state (pro
bably corrupted stack)
Segmentation fault (core dumped)
 
C

Chris M. Thomasson

Alf P. Steinbach said:
* (e-mail address removed):
I have a few questions about C++.

1. Of what use is a reference to a function? Why not just use a
pointer, which can be checked against NULL?

Why would you /want/ to have to check against 0?

[...]

I guess sometimes it can be useful. Think of the following contrived
example; quick pseudo-code:
______________________________________________________________
typedef void (*fp_handler) (struct foo*);


struct foo {
fp_handler custom_handler;
/* [...] */
};


fp_handler
foo_swap_custom_handler(
struct foo* const self,
fp_handler custom_handler
) {
fp_handler old = self->custom_handler;
self->custom_handler = custom_handler;
return old;
}


void
foo_do_something(
struct foo* const self
) {
/* [...] */

if (self->custom_handler) {
self->custom_handler(self);
} else {
foo_sys_default_handler(self);
}

/* [...] */
}
______________________________________________________________
 
A

Alf P. Steinbach

* Chris M. Thomasson:
Alf P. Steinbach said:
* (e-mail address removed):
I have a few questions about C++.

1. Of what use is a reference to a function? Why not just use a
pointer, which can be checked against NULL?

Why would you /want/ to have to check against 0?

[...]

I guess sometimes it can be useful.

Yah.

But...

"sometimes useful" != "good idea as the only mechanism to use"

Think of the following contrived
example; quick pseudo-code:
______________________________________________________________
typedef void (*fp_handler) (struct foo*);


struct foo {
fp_handler custom_handler;
/* [...] */
};


fp_handler
foo_swap_custom_handler(
struct foo* const self,
fp_handler custom_handler
) {
fp_handler old = self->custom_handler;
self->custom_handler = custom_handler;
return old;
}


void
foo_do_something(
struct foo* const self
) {
/* [...] */

if (self->custom_handler) {
self->custom_handler(self);
} else {
foo_sys_default_handler(self);
}

/* [...] */
}

It seems you didn't realize you were posting to [comp.lang.c++], but thought you
were posting to a C group?

Would go like this in C++:

class Foo;
typedef void (*FpHandler)( Foo& );

class Foo
{
private:
FpHandler myFpHandler;

public:
Foo(): myFpHandler( &sysDefaultHandler ) {}

FpHandler setHandler( FpHandler fph )
{
if( !fph ) { fph = &sysDefaultHandler; }
std::swap( fph, myFpHandler );
return fph;
}

void doSomething() { myFpHandler(); }
};


Cheers,

- Alf
 
A

Alf P. Steinbach

* Alf P. Steinbach:
* Chris M. Thomasson:
Alf P. Steinbach said:
* (e-mail address removed):
I have a few questions about C++.

1. Of what use is a reference to a function? Why not just use a
pointer, which can be checked against NULL?

Why would you /want/ to have to check against 0?

[...]

I guess sometimes it can be useful.

Yah.

But...

"sometimes useful" != "good idea as the only mechanism to use"

Think of the following contrived example; quick pseudo-code:
______________________________________________________________
typedef void (*fp_handler) (struct foo*);


struct foo {
fp_handler custom_handler;
/* [...] */
};


fp_handler
foo_swap_custom_handler(
struct foo* const self,
fp_handler custom_handler
) {
fp_handler old = self->custom_handler;
self->custom_handler = custom_handler;
return old;
}


void
foo_do_something(
struct foo* const self
) {
/* [...] */

if (self->custom_handler) {
self->custom_handler(self);
} else {
foo_sys_default_handler(self);
}

/* [...] */
}

It seems you didn't realize you were posting to [comp.lang.c++], but
thought you were posting to a C group?

Would go like this in C++:

class Foo;
typedef void (*FpHandler)( Foo& );

class Foo
{
private:
FpHandler myFpHandler;

public:
Foo(): myFpHandler( &sysDefaultHandler ) {}

FpHandler setHandler( FpHandler fph )
{
if( !fph ) { fph = &sysDefaultHandler; }
std::swap( fph, myFpHandler );
return fph;
}

void doSomething() { myFpHandler(); }
};

Uhm, add the missing argument. :)
 
C

Chris M. Thomasson

Alf P. Steinbach said:
* Chris M. Thomasson:
Alf P. Steinbach said:
* (e-mail address removed):
I have a few questions about C++.

1. Of what use is a reference to a function? Why not just use a
pointer, which can be checked against NULL?

Why would you /want/ to have to check against 0?

[...]

I guess sometimes it can be useful.

Yah.

But...

"sometimes useful" != "good idea as the only mechanism to use"
touché.



Think of the following contrived example; quick pseudo-code:
______________________________________________________________
[...]
______________________________________________________________

It seems you didn't realize you were posting to [comp.lang.c++], but
thought you were posting to a C group?

YIKES! You are correct Sir.


:^o



Would go like this in C++:

class Foo;
typedef void (*FpHandler)( Foo& );

class Foo
{
private:
FpHandler myFpHandler;

public:
Foo(): myFpHandler( &sysDefaultHandler ) {}

FpHandler setHandler( FpHandler fph )
{
if( !fph ) { fph = &sysDefaultHandler; }
std::swap( fph, myFpHandler );
return fph;
}

void doSomething() { myFpHandler(); }
};
;^)




Due to hosting requirements I need visits to <url:
http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :) Just going there is good. Linking
to it is even better! Thanks in advance!

Will do.
 
J

James Kanze

* Jeff Schwab:

[...]
Which if you think about it implies very different things at
the machine code level and at the source code level.

You keep insisting on this distinction. The standard doesn't
specify anything at all at the machine code level, and it
doesn't specify anything at the source code level which is
"calling a constructor". What it does specify is a
"parameterized nondeterministic abstract machine", which is uses
to define the semantics. (Despite the name, the specifications
of this abstract machine are very far from what one could
consider "machine code".) And this abstract machine very
definitely calls constructors---you can't talk about the
semantics of a C++ program without talking about constructors
being called.
Which I'm mentioning just because I think you're demonstrating
enough of active confusion to think that perhaps the standard
in this case refers to machine code or even less constraining
a recursive reference without base case to the abstract
machine. Well it doesn't, neither here nor (AFAIK) anywhere
else: the phrasing means that by definition you have a default
constructor if at the source code level you can call that
constructor without arguments, as you're doing above. :)

"can be called without arguments" is rather open with regards to
who is doing the calling. The standard calls the syntax in
question a "definition", not a "constructor call", and most
people I know would speak about "defining an object" at the
source code level. But of course, any competent C++ programmer
will be very aware that one of the results of the definition is
that the constructor will be called.
 
J

James Kanze

* blargg:

[...]
A placement new invocation is a little more than a direct
constructor call, yes, as I've already pointed out in this
thread (not to mention countless earlier threads); it might
resonably be described as an indirect constructor call.
But as I pointed out in the article you're replying to, but
misleadingly snipped by you, where instead you misleadingly
chose to discuss a different example, for the particular
example chosen by Jeff above, the standard, not surprisingly,
refers to the source code as a constructor call.

Where? The standard makes it perfectly clear that the above
will result in the definition of an object, whose lifetime
starts when control flow encounters the definition. The
standard also defines what it means for an object's lifetime to
start, and that includes calling the constructor. As far as I
can see, however, the standard refers to that bit of source code
as a definition, not as a constructor call.

We've been through this before. There is no syntax in the
standard which the standard calls a "constructor call" (unlike
the case for destructors). On can thus argue that at the source
code level, there is no such thing as "calling a constructor"
(and in certain contexts, it even makes sense to do so). The
standard does define what it means to call a constructor, and
under what circumstances the constructor will be called. And a
competent C++ programmer will certainly be aware which syntaxes
will result in the constructor being called (among other
things). If a programmer uses such a syntax, is he "calling the
constructor"? You seem to argue yes, but most other people I
know say no.
 
J

James Kanze

On May 18, 9:26 pm, (e-mail address removed) (blargg) wrote:
Sounds good, I was going to try to code an exception within an
exception but then I tried this in Cygwin:
try {
int *a = 0;
*a = 0;
}
catch ( ... ) {
cout << "uh oh\n";
}

So where's the exception here? There's undefined behavior in
the try block (which from a QoI point of view, should result in
the program crashing), and a catch, but no exception is thrown.
5 [main] a 2980 _cygtls::handle_exceptions: Error while dumping
state (probably corrupted stack)
Segmentation fault (core dumped)

It's a somewhat strange error message, but undefined behavior
is, well, undefined. (I get "Segmentation Fault (core dumped)"
under both Linux and Solaris, and a pop-up window with an error
message with VC++ under Windows.)
 
A

Alf P. Steinbach

* James Kanze:
* Jeff Schwab:
[...]
Which if you think about it implies very different things at
the machine code level and at the source code level.

You keep insisting on this distinction.

Yes. :)

The standard doesn't
specify anything at all at the machine code level,

Yes, I think that's correct -- which was my point.

and it
doesn't specify anything at the source code level which is
"calling a constructor".

Sorry, that's incorrect.

What it does specify is a
"parameterized nondeterministic abstract machine", which is uses
to define the semantics. (Despite the name, the specifications
of this abstract machine are very far from what one could
consider "machine code".) And this abstract machine very
definitely calls constructors---you can't talk about the
semantics of a C++ program without talking about constructors
being called.

That's true.

"can be called without arguments" is rather open with regards to
who is doing the calling.

Sorry, it's not, it refers to source code.

If you think "can be called" refers to anything but source code then you have to
demonstrate that the paragraph, with that non-source code interpretation, still
provides a clear cut definition of a default constructor, and not the least, one
that is consistent with what we "know" is a default constructor from the source
code interpretation, e.g. that T( int = 5 ) is a T default constructor.

You have repeatedly failed to do that earlier, throughout the years, so chances
would be slim of achieving it now, but,.

The standard calls the syntax in
question a "definition", not a "constructor call", and most
people I know would speak about "defining an object" at the
source code level.

Right, although extremely irrelevant. :)

Syntactically it's a definition, semantically it's one whose effect contains a
constructor call.

It could, with a little modification, be a definition containing an ordinary
function call, like 'int x = MessageBox( 0, "James, you're being silly",
"Look!", 0 )'. The standard would still call it a "definition", not an "ordinary
function call", and most C++ programmers I know would speak about "declaring a
variable" at the source code level...

But of course, any competent C++ programmer
will be very aware that one of the results of the definition is
that the constructor will be called.

Yes. :)


Cheers,

- Alf
 
A

Alf P. Steinbach

* James Kanze:
* blargg:
Jeff Schwab wrote:
Alf P. Steinbach wrote:
* Jeff Schwab:
[...]
It's not only a lack of clean syntax. How would you
directly call a constructor? Given something like:
auto std::string s;
The constructor is called by the system on your behalf, but
so is the destructor. Saying this is a "constructor call"
is no more meaningful than saying it's a "destructor call."
And so is space allocated and deallocated for the object.
Even simply using placement new involves extra machinery,
for example if creating a Derived object and the Derived
constructor throws, the compiler will then call the Base
destructor, then placement delete. That's a lot more than
simply calling the constructor,
A placement new invocation is a little more than a direct
constructor call, yes, as I've already pointed out in this
thread (not to mention countless earlier threads); it might
resonably be described as an indirect constructor call.
But as I pointed out in the article you're replying to, but
misleadingly snipped by you, where instead you misleadingly
chose to discuss a different example, for the particular
example chosen by Jeff above, the standard, not surprisingly,
refers to the source code as a constructor call.

Where?

Definition of default constructors.

The standard makes it perfectly clear that the above
will result in the definition of an object, whose lifetime
starts when control flow encounters the definition. The
standard also defines what it means for an object's lifetime to
start, and that includes calling the constructor. As far as I
can see, however, the standard refers to that bit of source code
as a definition, not as a constructor call.

See above.

We've been through this before. There is no syntax in the
standard which the standard calls a "constructor call" (unlike
the case for destructors).

That's correct.

On can thus argue that at the source
code level, there is no such thing as "calling a constructor"
(and in certain contexts, it even makes sense to do so).

One can argue, and it appears that you do, but one/you would be arguing for
meaninglessness, definitions that don't define, which is just silly.

The standard does define what it means to call a constructor,

Does it?

and under what circumstances the constructor will be called.
Yah.


And a
competent C++ programmer will certainly be aware which syntaxes
will result in the constructor being called (among other
things). If a programmer uses such a syntax, is he "calling the
constructor"? You seem to argue yes,
Yes.


but most other people I know say no.

I don't think so, I think you're mistaken about what they say. Anyway, adopting
any other convention than the one of the standard in this respect, is
meaningless and a way to have such extended debates as this one. Reaching
through umpteen years. But I can't just let the flat-Earth'ers be unchallenged
and thus appear to be correct, thus misguiding all those who rather follow and
conform than think for themselves. Happily, I know no flat-Earth'ers personally.


Cheers,

- Alf
 

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,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top