So it has been proven

P

Paul

So it has been proven that, in C++, a nonstatic member function is indeed
different from an ordinary function in more fundamental ways than simply
calling syntax.

I see most of the original arguers dropped out of the argument and those
that persued their argument have since quietly slipped away.

I guess its not important enough to those people but I always considered it
important to understand the basics.
GL.
 
P

Paul

Leigh Johnston said:
You have failed to prove anything whatsoever.


If any have slipped away then it is probably due to them being fed up with
your tedious, repetitive incorrect posts and your inability to accept your
mistakes.


The basics:

In C++ a member function is a member of a class not a member of an object.

HTH.

/Leigh

Leigh I have already requested that you stop replying to my posts , I don't
want to be nasty but that is all you seem to provoke. You have no
intelligence and I feel sorry for you. Go away unless you can produce some
reasonably intelligent conversation.

..
 
P

Paul

Leigh Johnston said:
Please feel free to killfile those with whom you disagree; it would mean a
lot less noise in this newsgroup but it would also mean that you would be
killfiling almost every poster in this newsgroup. Perhaps you should
simply stop posting here instead?

/Leigh
Why should I killfile everyone who has a moment of stupidness?
Most of these people realise their mistakes and stop making a fool of
themsleves, unlike you.
 
P

Paul

Leigh Johnston said:
I have been wrong in this newsgroup a few times (I am only human) and I
have publicly admitted my mistakes; I have yet to see you do likewise.

/Leigh
You have been proven an idiot.
 
M

Marcel Müller

Paul said:
So it has been proven that, in C++, a nonstatic member function is
indeed different from an ordinary function in more fundamental ways than
simply calling syntax.

In the C++ language: yes.
In common implementations: no.

But the handling of virtual functions and member function pointers adds
a new dimension of complexity. This does not apply to the implementation
of a member function itself, but to the implementation of member
function pointers. So sizeof(MemberFunctionPointer) is in general larger
or same than sizeof(FunctionPointer).

The calling convention is usually the same for void A::foo() and
void bar(A*). However, dereferencing void (A::*)() and void (*)(A*) is
in general a different story, since the really called method also
depends on the object type used to dereference the member function pointer.


Marcel
 
P

Paul

Marcel Müller said:
In the C++ language: yes.
In common implementations: no.

But the handling of virtual functions and member function pointers adds a
new dimension of complexity. This does not apply to the implementation of
a member function itself, but to the implementation of member function
pointers. So sizeof(MemberFunctionPointer) is in general larger or same
than sizeof(FunctionPointer).

The calling convention is usually the same for void A::foo() and
void bar(A*). However, dereferencing void (A::*)() and void (*)(A*) is in
general a different story, since the really called method also depends on
the object type used to dereference the member function pointer.
Seems like a fair assessment.
Also note that (A::*)() can only call itself with objects of type A or in a
derived heirarchy containing A. (*)(A*) does not have this restraint as the
pointer parameter can theoretically point to any type of object. Thus the
possibility of a different sequence of execution arises.

Example , the following ordinary_function cannot be done with (A::*)():

#include <iostream>
class Animal{public:
virtual void eat(){std::cout<< "Animal Eating"<< std::endl;}
virtual int getID()=0;
static int count;
};
class Dog: public Animal{
public:
void eat(){std::cout<< "Dog Eating"<< std::endl;}
int getID(){return 1;}
};
class Cat: public Animal{
public:
void eat(){std::cout<< "Cat Eating"<< std::endl;}
int getID(){return 0;}
};
int Animal::count =10;

Dog* overwriteCat(Animal* ptr){
delete ptr;
Dog* p = reinterpret_cast<Dog*>(ptr);
p = new Dog;
return p;
}

Cat* overwriteDog(Animal* ptr){
delete ptr;
Cat* p = reinterpret_cast<Cat*>(ptr);
p = new Cat;
return p;
}


void ordinary_function(Animal* obj){
Animal::count--;
std::cout<<"Address of obj: " <<obj << " ";
obj->eat();
if(obj->getID()){overwriteDog(obj);}
else {overwriteCat(obj);}
if(Animal::count){
ordinary_function(obj);
}
}

int main()
{
Cat* p_cat = new Cat;
Animal* p_anim = p_cat;

ordinary_function(p_cat);
}
 
R

Rolf Magnus

Paul said:
I see most of the original arguers dropped out of the argument and those
that persued their argument have since quietly slipped away.

Yes, that's because everything has been said multiple times already. You
opening new threads about the same topic over and over and over again won't
magically produce more arguments. So it shouldn't be much of a surprise that
people stop discussing it.
 
G

gwowen

Seems like a fair assessment.
Also note that (A::*)() can only call itself with objects of type A or ina
derived heirarchy containing A.

Unless you use a cast. If you subvert the type system, you can do
what the hell you want.
(*)(A*) does not have this restraint as the
pointer parameter can theoretically point to any type of object.

Only if you use a cast. If you subvert the type system, you can do
what the hell you want.
 
J

Juha Nieminen

Paul said:
So it has been proven that, in C++, a nonstatic member function is indeed
different from an ordinary function in more fundamental ways than simply
calling syntax.

I really think you should see a doctor because you have a severe
case of OCD.
 
P

Paul

Unless you use a cast. If you subvert the type system, you can do
what the hell you want.

No you cannot call anything , as I said you can only call objects of A or
derived.
Only if you use a cast. If you subvert the type system, you can do
what the hell you want.

So casting is "subverting the type system" in your mind?
You cannot do what the hell you want. There are limits to what a program can
do , and I pointed out there are limits to what a member fucntion can do
(casting or no casting).

If you were correct I would bang up a quick program, with a coupe of casts
in it , to go me a cuppa tea. LOL
The three people who posted after you have nothing intelligent to say, they
are just attempting to dilute the argument into a troll. Obviously they have
been defeated and they have nothing more to say than whine , moan and meke
derogatory insults, One of them said it has all been said already, but I
don't recall him proposing any argumental proof that an ordinary function is
the same as a member function ,He is obviously a liar too. It's up to you if
you want to think like those 3 idiots.

*shrug*
 
G

gwowen

No you cannot call anything , as I said you can only call objects of A or
derived.

Really? What does the following do?

#include <iostream>
class A {
int num;
int another_num;
public:
int f() { return num;}
void setnum(int x) {num = x;}
};

int main()
{
int z = 4;
A* foo = reinterpret_cast<A*> (&z);

std::cout << foo->f() << std::endl;
foo->setnum(7);
std::cout << z << std::endl;
}
 
P

Paul

Really? What does the following do?

You tell us what it does, its your code.
As I said , with member functions you can only only call objects of the type
or derived ( see the C++ standards) .


#include <iostream>
class A {
int num;
int another_num;
public:
int f() { return num;}
void setnum(int x) {num = x;}
};
int main(){
int z = 4;
A* foo = reinterpret_cast<A*> (&z);
std::cout << foo->f() << std::endl;
foo->setnum(7);
std::cout << z << std::endl;
}

This just looks like a buggy mess to me, I have no interest in such code.
 
G

gwowen

You tell us what it does, its your code.
As I said , with member functions you can only only call objects of the type
or derived ( see the C++ standards) .


This just looks like a buggy mess to me, I have no interest in such code.

Thank you. That's given me the first genuine belly laugh of what was
quite a stressful day.
 
G

gwowen

class A {
  int num;
  int another_num;
public:
  int f() { return num;}
  void setnum(int x) {num = x;}

};

should have said this:

class A {
public:
int num;
int another_num;
int f() { return num;}
void setnum(int x) {num = x;}
};

although I'd be surprised if it made any difference in practice.
Forgot my POD type can't have private data members. Bad me.
 
P

Paul

On Mar 2, 12:15 pm, gwowen <[email protected]> wrote:
Sorry this:
should have said this:
class A {
public:
int num;
int another_num;
int f() { return num;}
void setnum(int x) {num = x;}
};
although I'd be surprised if it made any difference in practice.
Forgot my POD type can't have private data members. Bad me.

What exactly are you trying to do ?
We can tell you if it can be done and if so how to do it.
 
G

gwowen

What exactly are you trying to do ?

It is you who claims my code is buggy, so you tell me. Have you tried
to compile and run the code. Is it standard compliant? Why? Does it
compile on Comeau in strict mode?

What does it do? How does it do it?

#include<iostream>
class A {
public:
int num;
int another_num;
int f() { return num;}
void setnum(int x) {num = x;}
};
int main()
{
int z = 4;
A* foo = reinterpret_cast<A*> (&z);

std::cout << foo->f() << std::endl;
foo->setnum(7);
std::cout << z << std::endl;
}

Now, the million dollar question, how does its behaviour differ from
the following code?

#include<iostream>
class A {
public:
int num;
int another_num;
};

int f(A*const this_) { return this_->num;}
void setnum(A*const this_,int x) {this_->num = x;}

int main()
{
int z = 4;
A* foo = reinterpret_cast<A*> (&z);

std::cout << f(foo) << std::endl;
setnum(foo,7);
std::cout << z << std::endl;
}
 
P

Paul

It is you who claims my code is buggy, so you tell me. Have you tried
to compile and run the code. Is it standard compliant? Why? Does it
compile on Comeau in strict mode?
What does it do? How does it do it?

If you cannot even explain your own code , or even its intended purpose then
I don't give a **** what it does or how it does it TBH.

<snip>
 
G

gwowen

If you cannot even explain your own code , or even its intended purpose then
I don't give a **** what it does or how it does it TBH.

I know what it does, thanks. It calls a non-static member function,
without an instantiated object, with predictable defined results.
Thereby showing that you don't need an object to call a (non-virtual)
member function [You do need one for virtual member functions, for
obvious reasons].

i.e. It does what you have repeatedly claimed to be impossible.

I'll explain it to you, now So pay attention

/*
class A is a POD-struct (no non-public data members, no virtual
functions).
This means that the address of any A object is the address of its
first data member
(an int) which means that I can type-pun between A* and int*
i.e. if sizeof(int) = N, the first N bytes of an "A object", is the
value representation of "num"
*/
class A {
public:
int num;
int another_num;
/*
This getter function returns the value of the first data member,
which for the reasons mentioned above is the same as *(int*)
(address of object)
*/
int f() { return num;}
/*
This setter function sets the first sizeof(N) bytes of the object
to the value representation of x
*/
void setnum(int x) {num = x;}
};



int main()
{
int z = 4;
/* tell the compiler to pretend the object at &z, is an A, not an
int */
A* foo = reinterpret_cast<A*> (&z);

/* Call the getter member function on our fictional A object. This
is ok, because we only access the A->num data member, and we know
thats precisely the storage occupied by z - which conveniently is the
same type. So the first N bytes at that address are the integer value
representation of 4 (the value of z)/ Since the methods aren't
virtual, we don't need to access a vtable, or any type information,
which is good, as there isn't any. We guarantee this compile-time
dispatch because A is POD. That's why I had to have public data
members */
std::cout << f(foo) << std::endl;
/* Call the setter member function on our fictional A object. This
is also ok, for all the same reasons. We set the first N bytes at
address foo = &z to the value representation of 7 */
setnum(foo,7);
/* And now, as if by magic, z is 7. The end. No A object was
created by this code. I lied to the compiler that there was one at
&z. I never allocated any storage, for example for the any data
member A::another_num */
std::cout << z << std::endl;
}

result: the code prints 4, then 7.

See also, the side-by-side code at
http://publib.boulder.ibm.com/infoc.../com.ibm.xlcpp8a.doc/language/ref/cplr035.htm
 
P

Paul

I know what it does, thanks. It calls a non-static member function,
without an instantiated object, with predictable defined results.
Thereby showing that you don't need an object to call a (non-virtual)
member function [You do need one for virtual member functions, for
obvious reasons].
i.e. It does what you have repeatedly claimed to be impossible.
I'll explain it to you, now So pay attention
/*
class A is a POD-struct (no non-public data members, no virtual
functions).
This means that the address of any A object is the address of its
first data member
(an int) which means that I can type-pun between A* and int*
i.e. if sizeof(int) = N, the first N bytes of an "A object", is the
value representation of "num"
*/
class A {
public:
int num;
int another_num;
/*
This getter function returns the value of the first data member,
which for the reasons mentioned above is the same as *(int*)
(address of object)
*/
int f() { return num;}
/*
This setter function sets the first sizeof(N) bytes of the object
to the value representation of x
*/
void setnum(int x) {num = x;}
};


int main()
{
int z = 4;
/* tell the compiler to pretend the object at &z, is an A, not an
int */
A* foo = reinterpret_cast<A*> (&z);
/* Call the getter member function on our fictional A object. This
is ok, because we only access the A->num data member, and we know
thats precisely the storage occupied by z - which conveniently is the
same type. So the first N bytes at that address are the integer value
representation of 4 (the value of z)/ Since the methods aren't
virtual, we don't need to access a vtable, or any type information,
which is good, as there isn't any. We guarantee this compile-time
dispatch because A is POD. That's why I had to have public data
members */

Error 'f' : identifier not found.
What language is this code supposed to be ?.
 

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

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,054
Latest member
LucyCarper

Latest Threads

Top