Thursday, October 11, 2018

Digest for comp.lang.c++@googlegroups.com - 21 updates in 7 topics

JiiPee <no@notvalid.com>: Oct 11 11:03PM +0100

They say (Bjarne?) that pure virtual class should not have any
data/member variables. Is this true? I created an example where I think
member variable seems to belong to the pure virtual base class:
 
#####################
 
class Animal
{
public:
    Animal(int age) : age_{age} {
    }
    virtual ~Animal() = 0; // make it pure virtual
    virtual void talk() {
    }
private:
    int age_;
};
 
inline Animal::~Animal()
{
}
 
class Dog : public Animal
{
public:
    Dog(int age) : Animal{ age } {
    }
    void talk() override {
        cout << "Meouw";
    }
};
 
##################
 
Where is the correct place for age_ assuming that *all animals have
age*. So lets assume that 100% all animals will have age-variable (they
need it). But its logical that Animal is pure virtual. So, where should
age_ belong to if not inside Animal class?
 
 
Or did I misunderstand something? I think somebody said pure virtual
interfaces should not have data/member variables. Did I misunderstand it?
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Oct 11 11:10PM +0100

On 11/10/2018 23:03, JiiPee wrote:
> belong to if not inside Animal class?
 
> Or did I misunderstand something? I think somebody said pure virtual
> interfaces should not have data/member variables. Did I misunderstand it?
 
The only reason to make a destructor pure is to force a class that would
otherwise not be abstract to be abstract to force derivation but this is
rarely necessary. If the class needs to be abstract it will have other
pure virtual methods. Perhaps you should make talk() pure virtual instead?
 
It is perfectly fine for abstract base classes to have member variables
unless the class is representing an *interface* in which case the
idiomatic thing to do is to not have any member variables.
 
/Flibble
 
--
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Oct 12 12:57AM +0200

On 12.10.2018 00:03, JiiPee wrote:
> They say (Bjarne?) that pure virtual class should not have any
> data/member variables.
 
"Pure virtual class" is not standard terminology. I think you mean a
pure interface class. Which is not standard C++ terminology, but a
descriptive term that indicates how the class is used.
 
A pure interface will usually not have data members, but it's a feature
of C++ that it /can/ have data members. One reason to not have data
members is that without data members, one can inherit from that
interface multiple times with no ill effects, e.g., an animal will not
wind up with multiple different ages. To avoid such problems, with data
members one is essentially restricted to either single inheritance, or
virtual inheritance, and the latter carries some run time overhead. But
for any given case this restriction may not necessarily matter, and it
must be balanced against the advantages such as simplicity with data
members versus complexity without, i.e. the usefulness of data members.
 
Non-virtual member functions can also be useful, e.g. as wrappers that
check preconditions and postconditions for the called virtual functions.
 
 
> private:
>     int age_;
> };
 
Consider what happens as time goes by. The animals will not age. If you
want them to have age values that reflect the passage of time in the
real world, you can use a birthdate (including the year, of course).
 
 
> age*. So lets assume that 100% all animals will have age-variable (they
> need it). But its logical that Animal is pure virtual. So, where should
> age_ belong to if not inside Animal class?
 
Putting the known common implementation and/or implementation support in
the base is generally OK.
 
There can be reasons not to do it, such as supporting general use of the
interface for arbitrary classes (you'd not want to impose per-instance
overhead on those not-really-animal classes), including, as mentioned,
general multiple inheritance, or, in a different direction, avoiding
headers that the implementation part needs. But it's generally OK.
 
 
> Or did I misunderstand something? I think somebody said pure virtual
> interfaces should not have data/member variables. Did I misunderstand it?
 
As a rule of thumb that works.
 
But in any given case one should, if possible, do what seems reasonable
for the case at hand, preferably after /informed/ consideration, but in
the worst case just gut feeling, and not blindly follow a rule of thumb.
 
Following mechanical rules that have worked for others is a nice
default, generally not a bad idea, but if software could be developed
only that way it would have been developed by cheap software robots.
 
I guess the main advice is to know the /rationale/ of the rules, why
they are recommendations that generally work out OK, so that one can
decide on an informed basis whether to follow them in any given case.
 
And that's what you're doing now, asking for rationale, so you're fine.
 
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Oct 12 01:00AM +0200

On 12.10.2018 00:57, Alf P. Steinbach wrote:
> [sniop]
> A pure interface will usually not have data members, but it's a feature
> of C++ that it /can/ have data members.
 
I meant to write, an *interface*.
 
When it has a data member it's no longer pure.
 
 
Cheers!,
 
- Alf
ram@zedat.fu-berlin.de (Stefan Ram): Oct 11 05:41PM

>struct X {
> int i;
...
>X *p = new X();
 
There is a new-initializer »()« (n4762 7.6.2.4p1).
It is interpreted according to the initialization
rules of 9.3 for direct-initialization (p18.2).
So, we got a default-initialization (9.3p7).
So, the default constructor is called (p7.1).
During the execution of this constructor,
»i« is default-initialized (10.9.2p9.3).
ram@zedat.fu-berlin.de (Stefan Ram): Oct 11 10:27PM

>They say (Bjarne?) that pure virtual class should not have any
>data/member variables.
 
You can implement the idea of an interfaces (similar to Java
or COM interfaces) by abstract C++ classes which only have
pure virtual functions.
 
The whole idea of an interface is not to lay down a specific
representation. There is nothing that speaks against addding
data to a class with some pure virtual functions, it just
does not represent the idea of an interface very well anymore.
 
>Where is the correct place for age_ assuming that *all animals have
>age*.
 
Maybe in another non-abstract base class that "implements"
the interface.
 
Maybe, you don't need an interface at all, just a normal
base class with some pure virtual functions?
 
Interfaces are not an end in themselves. They are only
implemented when needed.
Thiago Adams <thiago.adams@gmail.com>: Oct 11 10:21AM -0700

#include <stdio.h>
 
struct X {
int i;
};
 
 
int main()
{
X *p = new X();
X x = {};
printf("%d %d", p->i, x.i);
delete p;
}
 
This code is printing 0 0 in release mode. (VC++ 17)
 
Is it guarantee to initialize 'i' with '0'?
 
I tried to find the answer in but it is not clear.
 
https://en.cppreference.com/w/cpp/language/default_initialization
woodbrian77@gmail.com: Oct 11 12:33PM -0700

On Thursday, October 11, 2018 at 12:21:42 PM UTC-5, Thiago Adams wrote:
 
> int main()
> {
> X *p = new X();
 
You could also try:
 
X *p2 = new X;
 
 
In that case you would get undefined values.
 
 
Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net
 
 
jameskuyper@alumni.caltech.edu: Oct 11 01:21PM -0700

On Thursday, October 11, 2018 at 1:21:42 PM UTC-4, Thiago Adams wrote:
 
> int main()
> {
> X *p = new X();
 
"If there is no user-declared constructor for class X, a non-explicit constructor having no parameters is implicitly declared as defaulted
(9.4). An implicitly-declared default constructor is an inline public
member of its class." (10.3.4p4).
"The implicitly-defined default constructor performs the set of
initializations of the class that would be performed by a user-written
default constructor for that class with no ctor-initializer (10.9.2) and
an empty compound-statement." (10.3.4p7)
 
"In a non-delegating constructor, if a given potentially constructed
subobject is not designated by a meminitializer-id (including the case
where there is no mem-initializer-list because the constructor has no
ctor-initializer), then
[several options that don't apply]
— otherwise, the entity is default-initialized (9.3)." (10.9.2p9)
 
"To default-initialize an object of type T means:
(7.1) — If T is a (possibly cv-qualified) class type (Clause 10), ...
(7.2) — If T is an array type, ...
(7.3) — Otherwise, no initialization is performed." (9.3p7)
 
> }
 
> This code is printing 0 0 in release mode. (VC++ 17)
 
> Is it guarantee to initialize 'i' with '0'?
 
No.
Thiago Adams <thiago.adams@gmail.com>: Oct 11 01:58PM -0700


> > This code is printing 0 0 in release mode. (VC++ 17)
 
> > Is it guarantee to initialize 'i' with '0'?
 
> No.
 
Thanks, it helped to understand.
"Öö Tiib" <ootiib@hot.ee>: Oct 11 02:03PM -0700

On Thursday, 11 October 2018 20:21:42 UTC+3, Thiago Adams wrote:
 
> Is it guarantee to initialize 'i' with '0'?
 
> I tried to find the answer in but it is not clear.
 
> https://en.cppreference.com/w/cpp/language/default_initialization
 
The X is aggregate so these are guaranteed to default initialize
everything in *p and x:
 
X *p = new X();
X x = {};
 
And these leave *p and x uninitialized:
 
X *p = new X;
X x;
 
That means unless x is in static storage (there it is also
default initialized).
Jorgen Grahn <grahn+nntp@snipabacken.se>: Oct 11 01:45PM

On Mon, 2018-10-08, leigh.v.johnston@googlemail.com wrote:
...
> Just fuck off will you you horrible little man?
 
Just killfile him. You already know he's not speaking for anyone else
here, and not winning anyone over.
 
> /Leigh
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
gazelle@shell.xmission.com (Kenny McCormack): Oct 11 04:04PM

In article <slrnprul04.f78.grahn+nntp@frailea.sa.invalid>,
>> Just fuck off will you you horrible little man?
 
>Just killfile him. You already know he's not speaking for anyone else
>here, and not winning anyone over.
 
Have you ever heard the following fairly famous quote:
 
The only thing necessary for the triumph of evil is that good men do
nothing.
 
That's the general counter-argument to the idea of "Just ignore it" (when
dealing with trolls).
 
--
The randomly chosen signature file that would have appeared here is more than 4
lines long. As such, it violates one or more Usenet RFCs. In order to remain
in compliance with said RFCs, the actual sig can be found at the following URL:
http://user.xmission.com/~gazelle/Sigs/Pearls
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Oct 11 11:02AM -0700

On Thursday, October 11, 2018 at 12:04:24 PM UTC-4, Kenny McCormack wrote:
> The only thing necessary for the triumph of evil is that good
> men do nothing.
 
The gospel message triumphs over the enemy by going forth, because
even when it's rejected by men, yet has it gone forth, and it then
serves as solid documentation on Judgment Day of a rejection of the
free offer of salvation by Jesus Christ, such that they are without
excuse, and will even self-condemn their own soul to Hell when
standing before God seeing what it was they did to Him.
 
It is a fearful thing to fall into the hands of the living God:
 
https://www.biblegateway.com/passage/?search=Hebrews+10%3A30-31&version=KJV
 
30 For we know him that hath said, Vengeance belongeth
unto me, I will recompense, saith the Lord. And again,
==> The Lord shall judge his people.
31 It is a fearful thing to fall into the hands of the
living God.
 
-----
You do not see what Jesus is offering you, Kenny. You do not see
that I am pointing you to the only life preserver you'll ever re-
ceive to save your eternal soul. Instead, you mock and hate and
espouse all manner of the same in your slippery posts full of a
true hatred of God and all His teachings.
 
You are a dreadful man, Kenny, for all your ways are the ways of
death (today).
 
https://www.biblegateway.com/passage/?search=proverbs+14%3A12%2C+16%3A25&version=KJV
 
12 There is a way which seemeth right unto a man, but the
end thereof are the ways of death.
25 There is a way that seemeth right unto a man, but the
end thereof are the ways of death.
 
Said it twice. In the Bible, that's the equivalent of bold type.
 
--
Rick C. Hodgin
"Öö Tiib" <ootiib@hot.ee>: Oct 10 10:51PM -0700

On Thursday, 11 October 2018 01:01:07 UTC+3, Daniel wrote:
> }
> };
 
> (1) B<A>(); // fails, as expected
 
You mean by being most vexing parse?
 
> (2) B<A>(A(1)); // ?
 
> Is it for certain that the expression T() won't get evaluated in (2)?
 
Yes.
"Öö Tiib" <ootiib@hot.ee>: Oct 10 10:56PM -0700

On Thursday, 11 October 2018 08:51:52 UTC+3, Öö Tiib wrote:
 
> > (1) B<A>(); // fails, as expected
 
> You mean by being most vexing parse?
 
Nah ... mea culpa ... it isn't most vexing parse.
Fraser Ross <fraser.ross8ATbtinternet.com@com>: Oct 11 09:39AM +0100

On 10/10/2018 23:00, Daniel wrote:
> {
> }
> };
 
The class has a constructor so the default constructor is not implicitly
declared defaulted and hence you did not need to declare it deleted.
Its an old rule but the terminology has changed.
 
Fraser.
Daniel <danielaparker@gmail.com>: Oct 11 06:58AM -0700

On Thursday, October 11, 2018 at 1:51:52 AM UTC-4, Öö Tiib wrote:
> > };
 
> > (1) B<A>(); // fails, as expected
 
> You mean by being most vexing parse?
 
No, this fails because the template argument supplied doesn't have a default
constructor, so T() isn't defined.

> > (2) B<A>(A(1)); // ?
 
> > Is it for certain that the expression T() won't get evaluated in (2)?
 
> Yes.
 
Just want to be sure that no compiler would evaluate
the default parameter (and hence fail) if an actual parameter was passed.
 
Daniel
Tim Rentsch <txr@alumni.caltech.edu>: Oct 11 12:56AM -0700

> other characteristics as unsigned char and signed char just on
> the off chance that it might be useful for C++'s type overloading
> on operator << when encountering [u]int8_t,
 
That's a strawman argument. There are several reasons a C
implementation might choose to keep [u]int8_t distinct from the
character types that have nothing to do with C++. Also the
people who did the C++ implementation could provide their own
C implementation, and choose to keep the [u]int8_t types
separate precisely because they want C++ to take advantage
of that.
 
> not even sure that that would be legal: "extended" implies
> something different to the standard integer types, not something
> the same as a standard integer type.
 
I think you're grasping at straws here. Extended integer types
are called "extended" only because they are not standard integer
types. The set of standard integer types can have two or more
types that are "the same" but still are distinct types (and
indeed that is the case in most implementations, either int/long
or long/long long). The rules for integer conversion rank
tacitly acknowledge the possibility of extended integer types
that are "the same" but still are distinct types. Extended
integer types are always disjoint from standard integer types by
virtue of how they are defined. But being distinct doesn't imply
they can't be "the same": we have standard integer types that
are distinct but "the same", and extended integer types that are
distinct but "the same", so there is no reason to suppose that an
extended integer type, which is always distinct from every
standard integer type, can't be "the same" as a standard integer
type. Are you confusing the notions of being distinct and having
similar characteristics? The C and C++ standards clearly admit
the possibility of having two integer types that have the same
size, width, representation, alignment, and so forth, and yet
still are distinct types. I don't see any evidence that the rule
is any different for a standard integer type and an extended
integer type.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Oct 11 11:50AM +0100

On Thu, 11 Oct 2018 00:56:43 -0700
> C implementation, and choose to keep the [u]int8_t types
> separate precisely because they want C++ to take advantage
> of that.
 
I can't see how you can say it is a "strawman argument", which is a
ruse (that is, from Wikipedia: "an informal fallacy based on giving the
impression of refuting an opponent's argument, while actually refuting
an argument that was not presented by that opponent"). I was saying
that even if you were right, in a case where unsigned/signed char meet
the requirements for [u]int8_t you would not in practice come across an
"extended" type with the same size and other characteristics as that
unsigned/signed char for the [u]int8_t typedef. It was a prediction,
and a legitimate one even if you disagree with it. The refutation of
your argument, in which I indicated why you may not be right, was in my
text below ("I am not even sure that that would be legal ..."), which
you also disagree with.
 
Of course, the proof of the pudding as regards what happens "in
practice" is what compiler vendors do. I am content to be proved wrong
about that.
 
> still are distinct types. I don't see any evidence that the rule
> is any different for a standard integer type and an extended
> integer type.
 
I think this one has been beaten to death. I note that you don't agree
with me.
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Oct 10 09:49PM -0700

On 10/2/2018 12:28 PM, Rick C. Hodgin wrote:
> between those perturbations and the descent into fractals would
> yield some interesting things, kind of like how there are some
> constants encoded in fractals.  Perhaps there's more in there.
 
What about the following results from my own software:
 
https://plus.google.com/101799841244447089430/posts/19LK2c9tv9i
 
https://plus.google.com/101799841244447089430/posts/hhVMw7eB2fx
 
They kind of look like some strange simulated Hubble images.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: