Topic: Will the "POD's Revisited" proposal allow me to do this?
Author: "terminator(jam)" <farid.mehrabi@gmail.com>
Date: Wed, 15 Aug 2007 13:13:00 CST Raw View
On Aug 12, 6:14 pm, diener896092_no_spam_h...@bellsouth.net (Edward
Diener) wrote:
> tonytinker2...@yahoo.com wrote:
> > Please read past this first part. I promise this is about C++.
>
> > In C# you can create properties within a class something like this:
>
> > class A
> > {
> > public int Count
> > {
> > get { return count; }
> > set { count = value; }
> > }
> > private int count;
> > }
>
> > Given a reference to an "A" object called "a", the property allows the
> > "count" member to be accessed as:
>
> > a.Count = 5;
> > a.Count = a.Count + 5;
>
> > There is some interest in providing a similar mechanism for use with C
> > ++. There are several articles on the net explaining how to provide
> > this functionality. Unfortunately, all of the mechanisms that I looked
> > at add overhead to the class for each property defined. Since this is
> > primarily syntactic-sugar after all, IMHO adding overhead to support
> > this sort of thing is unacceptable.
>
> I do not agree with the last argument. Even if one adds something which
> is syntactic sugar, ie. makes it clearer to use a programming construct
> while adding no new functionality, the idea that this must somehow
> provide zero-overhead is not an acceptable position in my mind.
>
> Whenever some feature is added to the language, via a language change or
> library addition, the zero-overhead argument is only valid if it applies
> to those NOT using the feature being penalized with added overhead. I
> see nothing wrong with adding something to C++, even in the form of
> syntactic sugar, which adds overhead only if used.
>
I believe that inner classes can increase encapsulation and
readability.
regards,
FM.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "terminator(jam)" <farid.mehrabi@gmail.com>
Date: Wed, 15 Aug 2007 13:19:29 CST Raw View
On Aug 10, 4:15 pm, Falk Tannh user <falk.tannhau...@crf.canon.fr>
wrote:
> terminator(jam) wrote:
> > I think something like a java-ish inner class would be more helpful
> > (general).what I mean is a struct that needs this pointer of the
> > nesting class to have been loaded previously(just like an instance
> > member function):
>
> > class A{
> > public:
> > int i;
> > auto struct inner{//syntax differs from java and does not exist
> > in c++
> > int data;
> > void f(){
> > i;//ok reference A::i;
> > A::this -> i;//same as above
> > data;//ordinary access to member
> > this -> data;;//same as above
> > };
> > };
>
> > void af(){
> > inner ob;//ok A::this is loaded by af
> > ob.f();
> > };
> > };
>
> > static A::inner stob;//error no this loaded for A
> > A a;//define an A
> > a.inner.f();//ok:load A::this with &a,reference a temporary A::inner
> > for a, call f() on the temporary.
>
> Inner classes already can be simulated in the current language - just
> put a reference to the outer class instance inside and initialize it in
> the constructor:
> ________________________________________________________
> class A
> {
> int i;
> public:
> A(int i) : i(i) {}
>
> class inner
> {
> A& outer;
> public:
> inner(A& a) : outer(a) {}
> int f() { return outer.i; }
> };
>
> int af() { inner ob(*this); return i * ob.f(); }
>
> };
>
> int main()
> {
> A a(7);
> return a.af() - A::inner(a).f();}
>
> ________________________________________________________
>
I have written a template with similar specifications in my personal
library but I do not like to use it.The reason is that one can not
simply mark functions to be called based on const/volatile state of
the outer class, more over I can not rely on the ability of compiler
to remove unnecessary initialization of the reference declared in the
inner class with this approach.
If the compiler becomes capabe of using inner classes one need not
worry where the this pointer is loaded.Normally when you call an
instance method the this pointer is loaded either at stack top or a
specific register ,in the later case when an instance member function
is called within another one on the same object the compiler does need
to reload the this pointer.IMHO even very weak compilers do better
optimizations on the this pointer compared to other parts of
program.Now when you call an inner class within an instance method ,
the compiler does not need to reload the this pointer (just as it did
with instance methods).
regards,
FM.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "terminator(jam)" <farid.mehrabi@gmail.com>
Date: Wed, 15 Aug 2007 13:20:18 CST Raw View
On Aug 11, 5:38 pm, xrebor...@gmail.com wrote:
> tonytinker's approach is very difficult to use. Too many redundant
> code is required.
>
> Properties can be simulated by inner classes. Terminator and Falk have
> given the sample code. However, these approaches add an overhead for
> each property for each object, since each inner object must hold a
> pointer to the outer object.
>
> I have an idea to simulate properties in c++ without overhead:
>
> struct type
> {
> public:
> struct
> {
> operator int() const
> {
> return ((type*)(((char*)this)-(char*)((type*)0)->Value))->Value;
> }
> const int& operator=(int X)
> {
> return ((type*)(((char*)this)-(char*)((type*)0)->Value))->Value
> = X;
> }
> } value;
> private:
> int Value;
>
> };
>
> Using macro to simplify the coding, I think this approach can be
> easily used when there're many properties.
>
> On Aug 9, 11:35 pm, tonytinker2...@yahoo.com wrote:
>
>
>
>
>
> > Please read past this first part. I promise this is about C++.
>
> > In C# you can create properties within a class something like this:
>
> > class A
> > {
> > public int Count
> > {
> > get { return count; }
> > set { count = value; }
> > }
> > private int count;
>
> > }
>
> > Given a reference to an "A" object called "a", the property allows the
> > "count" member to be accessed as:
>
> > a.Count = 5;
> > a.Count = a.Count + 5;
>
> > There is some interest in providing a similar mechanism for use with C
> > ++. There are several articles on the net explaining how to provide
> > this functionality. Unfortunately, all of the mechanisms that I looked
> > at add overhead to the class for each property defined. Since this is
> > primarily syntactic-sugar after all, IMHO adding overhead to support
> > this sort of thing is unacceptable.
>
> > I have been trying to come up with a zero-overhead, portable property
> > mechanism, free of undefined-behavior according to the standard, but
> > every approach that I have come up with has failed. Recently I read a
> > proposal that gave me an idea that this may be possible in a future
> > release of the C++ standard.
>
> > Unrelated to properties, someone mentioned this proposal (POD's
> > Revisited n2172) on comp.lang.c++ (maybe .moderated) the other day. If
> > I understand this proposal, it appears to relax the definition of POD,
> > or rather, it creates a new definition of layout compatible structs,
> > classes, and unions that allow certain things that current PODs don't
> > allow. Maybe this is what I need to provide zero overhead properties
> > in a portable manner. Here is the idea:
>
> > // Given this data class:
>
> > class Data
> > {
> > public:
> > Data() : m_a( 3 ) , m_b( 3.3 ) {}
>
> > int get_a() const { return m_a; }
> > void set_a( int value ) { m_a = value; }
>
> > double get_b() const { return m_b; }
> > void set_b( double value ) { m_b = value; }
>
> > private:
> > int m_a;
> > double m_b;
>
> > };
>
> > // I believe each of the following is a POD-struct
> > // according to the current standard.
> > // Please correct me if I am wrong.
>
> > struct DataPtr
> > {
> > Data * m_pData;
>
> > };
>
> > struct DataProp_a
> > {
> > Data * m_pData;
> > int operator=( int value )
> > {
> > m_pData->set_a( value );
> > return value;
> > }
> > operator int() const
> > {
> > return m_pData->get_a();
> > }
>
> > };
>
> > struct DataProp_b
> > {
> > Data * m_pData;
> > double operator=( double value )
> > {
> > m_pData->set_b( value );
> > return value;
> > }
> > operator double() const
> > {
> > return m_pData->get_b();
> > }
>
> > };
>
> > // Given that the above are PODs, the following is a POD-union. (Yes?)
>
> > union DataProxy
> > {
> > DataPtr _ptr_;
> > DataProp_a a;
> > DataProp_b b;
>
> > };
>
> > // So this allows me to do the following
> > // according to the current standard.
>
> > #include <iostream>
>
> > int main()
> > {
> > Data d;
>
> > DataProxy dp;
> > dp._ptr_.m_pData = &d;
>
> > int a = dp.a;
> > double b = dp.b;
>
> > std::cout << "a=" << dp.a << std::endl;
> > std::cout << "b=" << dp.b << std::endl;
>
> > dp.a = 5;
> > dp.b = 5.5;
>
> > std::cout << "a=" << dp.a << std::endl;
> > std::cout << "b=" << dp.b << std::endl;
>
> > getchar();
> > return 0;
>
> > }
>
> > The sizeof(DataProxy) is the size of a single pointer (no overhead).
>
> > Of course, to make this usable, a lot more would need to be added.
> > Handling various int and double operations as well as more complex
> > data types such std::string, just to name a few, but I think this
> > approach could be extended to do these things. It is also easy to add
> > a wrapper class that implements "pointer" functionality such as what
> > an iterator would provide.
>
> > This all seems to compile and execute on VCPP and G++ with no
> > unexpected side afects, but there is a glaring hole in all of this.
> > The pointer within each POD struct is not protected from direct access
> > such as:
>
> > dp.a.m_pData = 0;
>
> > IIUC, the current standard does not allow the pointer member in the
> > POD structs to have any access specifier other than public, otherwise
> > these are no longer PODs and the ability to access the pointer from
> > different struct members of the union goes away (becomes undefined
> > behavior).
>
> > This is where the new POD proposal comes in. I believe if this
> > proposal were accepted it would allow the pointers to be declared
> > private. I believe the proposal would also allow a common base class
> > to hold the pointer as long as the derived classes (implementing the
> > operator= and user defined converions) didn't have any data members.
>
> > So, a few questions:
>
> > 1)Is the above implementation standards conforming?
>
> > 2)If the POD proposal is accepted, would this be standards conforming
> > with the pointers defined as private?
>
> > 3)Does it look like the POD proposal has traction? Do you think it
> > will be approved?
>
> > 4)I have already tried making the pointers private, with associated
> > friends to initialize the pointer and a few other necessary changes.
> > This seems to work properly today with VCPP and G++ even though is is
> > technically undefined behavior. Do you think this is a safe approach
> > (with the private pointers) to use today with current compilers. I
> > mean, does anyone know of an actual compiler that would have a problem
> > with implementing this today?
>
> > Thanks in advance for you consideration.
>
> > Tony Jorgenson
>
I would rather leave the 'thunk' and cast to the compiler.That is why
I do not like to code like this.
regards,
FM.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: tonytinker2000@yahoo.com
Date: Thu, 9 Aug 2007 09:35:20 CST Raw View
Please read past this first part. I promise this is about C++.
In C# you can create properties within a class something like this:
class A
{
public int Count
{
get { return count; }
set { count = value; }
}
private int count;
}
Given a reference to an "A" object called "a", the property allows the
"count" member to be accessed as:
a.Count = 5;
a.Count = a.Count + 5;
There is some interest in providing a similar mechanism for use with C
++. There are several articles on the net explaining how to provide
this functionality. Unfortunately, all of the mechanisms that I looked
at add overhead to the class for each property defined. Since this is
primarily syntactic-sugar after all, IMHO adding overhead to support
this sort of thing is unacceptable.
I have been trying to come up with a zero-overhead, portable property
mechanism, free of undefined-behavior according to the standard, but
every approach that I have come up with has failed. Recently I read a
proposal that gave me an idea that this may be possible in a future
release of the C++ standard.
Unrelated to properties, someone mentioned this proposal (POD's
Revisited n2172) on comp.lang.c++ (maybe .moderated) the other day. If
I understand this proposal, it appears to relax the definition of POD,
or rather, it creates a new definition of layout compatible structs,
classes, and unions that allow certain things that current PODs don't
allow. Maybe this is what I need to provide zero overhead properties
in a portable manner. Here is the idea:
// Given this data class:
class Data
{
public:
Data() : m_a( 3 ) , m_b( 3.3 ) {}
int get_a() const { return m_a; }
void set_a( int value ) { m_a = value; }
double get_b() const { return m_b; }
void set_b( double value ) { m_b = value; }
private:
int m_a;
double m_b;
};
// I believe each of the following is a POD-struct
// according to the current standard.
// Please correct me if I am wrong.
struct DataPtr
{
Data * m_pData;
};
struct DataProp_a
{
Data * m_pData;
int operator=( int value )
{
m_pData->set_a( value );
return value;
}
operator int() const
{
return m_pData->get_a();
}
};
struct DataProp_b
{
Data * m_pData;
double operator=( double value )
{
m_pData->set_b( value );
return value;
}
operator double() const
{
return m_pData->get_b();
}
};
// Given that the above are PODs, the following is a POD-union. (Yes?)
union DataProxy
{
DataPtr _ptr_;
DataProp_a a;
DataProp_b b;
};
// So this allows me to do the following
// according to the current standard.
#include <iostream>
int main()
{
Data d;
DataProxy dp;
dp._ptr_.m_pData = &d;
int a = dp.a;
double b = dp.b;
std::cout << "a=" << dp.a << std::endl;
std::cout << "b=" << dp.b << std::endl;
dp.a = 5;
dp.b = 5.5;
std::cout << "a=" << dp.a << std::endl;
std::cout << "b=" << dp.b << std::endl;
getchar();
return 0;
}
The sizeof(DataProxy) is the size of a single pointer (no overhead).
Of course, to make this usable, a lot more would need to be added.
Handling various int and double operations as well as more complex
data types such std::string, just to name a few, but I think this
approach could be extended to do these things. It is also easy to add
a wrapper class that implements "pointer" functionality such as what
an iterator would provide.
This all seems to compile and execute on VCPP and G++ with no
unexpected side afects, but there is a glaring hole in all of this.
The pointer within each POD struct is not protected from direct access
such as:
dp.a.m_pData = 0;
IIUC, the current standard does not allow the pointer member in the
POD structs to have any access specifier other than public, otherwise
these are no longer PODs and the ability to access the pointer from
different struct members of the union goes away (becomes undefined
behavior).
This is where the new POD proposal comes in. I believe if this
proposal were accepted it would allow the pointers to be declared
private. I believe the proposal would also allow a common base class
to hold the pointer as long as the derived classes (implementing the
operator= and user defined converions) didn't have any data members.
So, a few questions:
1)Is the above implementation standards conforming?
2)If the POD proposal is accepted, would this be standards conforming
with the pointers defined as private?
3)Does it look like the POD proposal has traction? Do you think it
will be approved?
4)I have already tried making the pointers private, with associated
friends to initialize the pointer and a few other necessary changes.
This seems to work properly today with VCPP and G++ even though is is
technically undefined behavior. Do you think this is a safe approach
(with the private pointers) to use today with current compilers. I
mean, does anyone know of an actual compiler that would have a problem
with implementing this today?
Thanks in advance for you consideration.
Tony Jorgenson
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "terminator(jam)" <farid.mehrabi@gmail.com>
Date: Thu, 9 Aug 2007 17:24:11 CST Raw View
On Aug 9, 6:35 pm, tonytinker2...@yahoo.com wrote:
> Please read past this first part. I promise this is about C++.
>
> In C# you can create properties within a class something like this:
>
> class A
> {
> public int Count
> {
> get { return count; }
> set { count = value; }
> }
> private int count;
>
> }
>
> Given a reference to an "A" object called "a", the property allows the
> "count" member to be accessed as:
>
> a.Count = 5;
> a.Count = a.Count + 5;
>
> There is some interest in providing a similar mechanism for use with C
> ++. There are several articles on the net explaining how to provide
> this functionality. Unfortunately, all of the mechanisms that I looked
> at add overhead to the class for each property defined. Since this is
> primarily syntactic-sugar after all, IMHO adding overhead to support
> this sort of thing is unacceptable.
>
> I have been trying to come up with a zero-overhead, portable property
> mechanism, free of undefined-behavior according to the standard, but
> every approach that I have come up with has failed. Recently I read a
> proposal that gave me an idea that this may be possible in a future
> release of the C++ standard.
>
> Unrelated to properties, someone mentioned this proposal (POD's
> Revisited n2172) on comp.lang.c++ (maybe .moderated) the other day. If
> I understand this proposal, it appears to relax the definition of POD,
> or rather, it creates a new definition of layout compatible structs,
> classes, and unions that allow certain things that current PODs don't
> allow. Maybe this is what I need to provide zero overhead properties
> in a portable manner. Here is the idea:
>
> // Given this data class:
>
> class Data
> {
> public:
> Data() : m_a( 3 ) , m_b( 3.3 ) {}
>
> int get_a() const { return m_a; }
> void set_a( int value ) { m_a = value; }
>
> double get_b() const { return m_b; }
> void set_b( double value ) { m_b = value; }
>
> private:
> int m_a;
> double m_b;
>
> };
>
> // I believe each of the following is a POD-struct
> // according to the current standard.
> // Please correct me if I am wrong.
>
> struct DataPtr
> {
> Data * m_pData;
>
> };
>
> struct DataProp_a
> {
> Data * m_pData;
> int operator=( int value )
> {
> m_pData->set_a( value );
> return value;
> }
> operator int() const
> {
> return m_pData->get_a();
> }
>
> };
>
> struct DataProp_b
> {
> Data * m_pData;
> double operator=( double value )
> {
> m_pData->set_b( value );
> return value;
> }
> operator double() const
> {
> return m_pData->get_b();
> }
>
> };
>
> // Given that the above are PODs, the following is a POD-union. (Yes?)
>
> union DataProxy
> {
> DataPtr _ptr_;
> DataProp_a a;
> DataProp_b b;
>
> };
>
> // So this allows me to do the following
> // according to the current standard.
>
> #include <iostream>
>
> int main()
> {
> Data d;
>
> DataProxy dp;
> dp._ptr_.m_pData = &d;
>
> int a = dp.a;
> double b = dp.b;
>
> std::cout << "a=" << dp.a << std::endl;
> std::cout << "b=" << dp.b << std::endl;
>
> dp.a = 5;
> dp.b = 5.5;
>
> std::cout << "a=" << dp.a << std::endl;
> std::cout << "b=" << dp.b << std::endl;
>
> getchar();
> return 0;
>
> }
>
> The sizeof(DataProxy) is the size of a single pointer (no overhead).
>
> Of course, to make this usable, a lot more would need to be added.
> Handling various int and double operations as well as more complex
> data types such std::string, just to name a few, but I think this
> approach could be extended to do these things. It is also easy to add
> a wrapper class that implements "pointer" functionality such as what
> an iterator would provide.
>
> This all seems to compile and execute on VCPP and G++ with no
> unexpected side afects, but there is a glaring hole in all of this.
> The pointer within each POD struct is not protected from direct access
> such as:
>
> dp.a.m_pData = 0;
>
> IIUC, the current standard does not allow the pointer member in the
> POD structs to have any access specifier other than public, otherwise
> these are no longer PODs and the ability to access the pointer from
> different struct members of the union goes away (becomes undefined
> behavior).
>
> This is where the new POD proposal comes in. I believe if this
> proposal were accepted it would allow the pointers to be declared
> private. I believe the proposal would also allow a common base class
> to hold the pointer as long as the derived classes (implementing the
> operator= and user defined converions) didn't have any data members.
>
> So, a few questions:
>
> 1)Is the above implementation standards conforming?
>
> 2)If the POD proposal is accepted, would this be standards conforming
> with the pointers defined as private?
>
> 3)Does it look like the POD proposal has traction? Do you think it
> will be approved?
>
> 4)I have already tried making the pointers private, with associated
> friends to initialize the pointer and a few other necessary changes.
> This seems to work properly today with VCPP and G++ even though is is
> technically undefined behavior. Do you think this is a safe approach
> (with the private pointers) to use today with current compilers. I
> mean, does anyone know of an actual compiler that would have a problem
> with implementing this today?
>
> Thanks in advance for you consideration.
>
I think something like a java-ish inner class would be more helpful
(general).what I mean is a struct that needs this pointer of the
nesting class to have been loaded previously(just like an instance
member function):
class A{
public:
int i;
auto struct inner{//syntax differs from java and does not exist
in c++
int data;
void f(){
i;//ok reference A::i;
A::this -> i;//same as above
data;//ordinary access to member
this -> data;;//same as above
};
};
void af(){
inner ob;//ok A::this is loaded by af
ob.f();
};
};
static A::inner stob;//error no this loaded for A
A a;//define an A
a.inner.f();//ok:load A::this with &a,reference a temporary A::inner
for a, call f() on the temporary.
regards,
FM.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?ISO-8859-1?Q?Falk_Tannh=E4user?= <falk.tannhauser@crf.canon.fr>
Date: Fri, 10 Aug 2007 07:15:42 CST Raw View
terminator(jam) wrote:
> I think something like a java-ish inner class would be more helpful
> (general).what I mean is a struct that needs this pointer of the
> nesting class to have been loaded previously(just like an instance
> member function):
>
> class A{
> public:
> int i;
> auto struct inner{//syntax differs from java and does not exist
> in c++
> int data;
> void f(){
> i;//ok reference A::i;
> A::this -> i;//same as above
> data;//ordinary access to member
> this -> data;;//same as above
> };
> };
>
> void af(){
> inner ob;//ok A::this is loaded by af
> ob.f();
> };
> };
>
> static A::inner stob;//error no this loaded for A
> A a;//define an A
> a.inner.f();//ok:load A::this with &a,reference a temporary A::inner
> for a, call f() on the temporary.
Inner classes already can be simulated in the current language - just
put a reference to the outer class instance inside and initialize it in
the constructor:
________________________________________________________
class A
{
int i;
public:
A(int i) : i(i) {}
class inner
{
A& outer;
public:
inner(A& a) : outer(a) {}
int f() { return outer.i; }
};
int af() { inner ob(*this); return i * ob.f(); }
};
int main()
{
A a(7);
return a.af() - A::inner(a).f();
}
________________________________________________________
Falk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: xreborner@gmail.com
Date: Sat, 11 Aug 2007 08:38:17 CST Raw View
tonytinker's approach is very difficult to use. Too many redundant
code is required.
Properties can be simulated by inner classes. Terminator and Falk have
given the sample code. However, these approaches add an overhead for
each property for each object, since each inner object must hold a
pointer to the outer object.
I have an idea to simulate properties in c++ without overhead:
struct type
{
public:
struct
{
operator int() const
{
return ((type*)(((char*)this)-(char*)((type*)0)->Value))->Value;
}
const int& operator=(int X)
{
return ((type*)(((char*)this)-(char*)((type*)0)->Value))->Value
= X;
}
} value;
private:
int Value;
};
Using macro to simplify the coding, I think this approach can be
easily used when there're many properties.
On Aug 9, 11:35 pm, tonytinker2...@yahoo.com wrote:
> Please read past this first part. I promise this is about C++.
>
> In C# you can create properties within a class something like this:
>
> class A
> {
> public int Count
> {
> get { return count; }
> set { count = value; }
> }
> private int count;
>
> }
>
> Given a reference to an "A" object called "a", the property allows the
> "count" member to be accessed as:
>
> a.Count = 5;
> a.Count = a.Count + 5;
>
> There is some interest in providing a similar mechanism for use with C
> ++. There are several articles on the net explaining how to provide
> this functionality. Unfortunately, all of the mechanisms that I looked
> at add overhead to the class for each property defined. Since this is
> primarily syntactic-sugar after all, IMHO adding overhead to support
> this sort of thing is unacceptable.
>
> I have been trying to come up with a zero-overhead, portable property
> mechanism, free of undefined-behavior according to the standard, but
> every approach that I have come up with has failed. Recently I read a
> proposal that gave me an idea that this may be possible in a future
> release of the C++ standard.
>
> Unrelated to properties, someone mentioned this proposal (POD's
> Revisited n2172) on comp.lang.c++ (maybe .moderated) the other day. If
> I understand this proposal, it appears to relax the definition of POD,
> or rather, it creates a new definition of layout compatible structs,
> classes, and unions that allow certain things that current PODs don't
> allow. Maybe this is what I need to provide zero overhead properties
> in a portable manner. Here is the idea:
>
> // Given this data class:
>
> class Data
> {
> public:
> Data() : m_a( 3 ) , m_b( 3.3 ) {}
>
> int get_a() const { return m_a; }
> void set_a( int value ) { m_a = value; }
>
> double get_b() const { return m_b; }
> void set_b( double value ) { m_b = value; }
>
> private:
> int m_a;
> double m_b;
>
> };
>
> // I believe each of the following is a POD-struct
> // according to the current standard.
> // Please correct me if I am wrong.
>
> struct DataPtr
> {
> Data * m_pData;
>
> };
>
> struct DataProp_a
> {
> Data * m_pData;
> int operator=( int value )
> {
> m_pData->set_a( value );
> return value;
> }
> operator int() const
> {
> return m_pData->get_a();
> }
>
> };
>
> struct DataProp_b
> {
> Data * m_pData;
> double operator=( double value )
> {
> m_pData->set_b( value );
> return value;
> }
> operator double() const
> {
> return m_pData->get_b();
> }
>
> };
>
> // Given that the above are PODs, the following is a POD-union. (Yes?)
>
> union DataProxy
> {
> DataPtr _ptr_;
> DataProp_a a;
> DataProp_b b;
>
> };
>
> // So this allows me to do the following
> // according to the current standard.
>
> #include <iostream>
>
> int main()
> {
> Data d;
>
> DataProxy dp;
> dp._ptr_.m_pData = &d;
>
> int a = dp.a;
> double b = dp.b;
>
> std::cout << "a=" << dp.a << std::endl;
> std::cout << "b=" << dp.b << std::endl;
>
> dp.a = 5;
> dp.b = 5.5;
>
> std::cout << "a=" << dp.a << std::endl;
> std::cout << "b=" << dp.b << std::endl;
>
> getchar();
> return 0;
>
> }
>
> The sizeof(DataProxy) is the size of a single pointer (no overhead).
>
> Of course, to make this usable, a lot more would need to be added.
> Handling various int and double operations as well as more complex
> data types such std::string, just to name a few, but I think this
> approach could be extended to do these things. It is also easy to add
> a wrapper class that implements "pointer" functionality such as what
> an iterator would provide.
>
> This all seems to compile and execute on VCPP and G++ with no
> unexpected side afects, but there is a glaring hole in all of this.
> The pointer within each POD struct is not protected from direct access
> such as:
>
> dp.a.m_pData = 0;
>
> IIUC, the current standard does not allow the pointer member in the
> POD structs to have any access specifier other than public, otherwise
> these are no longer PODs and the ability to access the pointer from
> different struct members of the union goes away (becomes undefined
> behavior).
>
> This is where the new POD proposal comes in. I believe if this
> proposal were accepted it would allow the pointers to be declared
> private. I believe the proposal would also allow a common base class
> to hold the pointer as long as the derived classes (implementing the
> operator= and user defined converions) didn't have any data members.
>
> So, a few questions:
>
> 1)Is the above implementation standards conforming?
>
> 2)If the POD proposal is accepted, would this be standards conforming
> with the pointers defined as private?
>
> 3)Does it look like the POD proposal has traction? Do you think it
> will be approved?
>
> 4)I have already tried making the pointers private, with associated
> friends to initialize the pointer and a few other necessary changes.
> This seems to work properly today with VCPP and G++ even though is is
> technically undefined behavior. Do you think this is a safe approach
> (with the private pointers) to use today with current compilers. I
> mean, does anyone know of an actual compiler that would have a problem
> with implementing this today?
>
> Thanks in advance for you consideration.
>
> Tony Jorgenson
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html ]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?iso-8859-1?q?Pedro_Lamar=E3o?= <pedro.lamarao@gmail.com>
Date: Sun, 12 Aug 2007 00:48:17 CST Raw View
On 11 ago, 11:38, xrebor...@gmail.com wrote:
> tonytinker's approach is very difficult to use. Too many redundant
> code is required.
>
> Properties can be simulated by inner classes. Terminator and Falk have
> given the sample code. However, these approaches add an overhead for
> each property for each object, since each inner object must hold a
> pointer to the outer object.
>
> I have an idea to simulate properties in c++ without overhead:
Your approach gives me overhead, as follows.
[pedro@localhost Projetos]$ cat hm.cpp
#include <iostream>
struct type
{
public:
struct
{
operator int() const
{
return ((type*)(((char*)this)-(char*)((type*)0)->Value))->Value;
}
const int& operator=(int X)
{
return ((type*)(((char*)this)-(char*)((type*)0)->Value))->Value
= X;
}
} value;
private:
int Value;
};
int
main (int argc, char* argv[]) {
std::cout << sizeof(type) << std::endl;
return 0;
}
[pedro@localhost Projetos]$ g++ hm.cpp -o hm
hm.cpp: In member function 'type::<anonymous struct>::operator int()
const':
hm.cpp:10: warning: invalid access to non-static data member
'type::Value' of NULL object
hm.cpp:10: warning: (perhaps the 'offsetof' macro was used
incorrectly)
hm.cpp: In member function 'const int& type::<anonymous
struct>::operator=(int)':
hm.cpp:14: warning: invalid access to non-static data member
'type::Value' of NULL object
hm.cpp:14: warning: (perhaps the 'offsetof' macro was used
incorrectly)
[pedro@localhost Projetos]$ ./hm
8
[pedro@localhost Projetos]$ g++ -v
Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
infodir=/usr/share/info --enable-shared --enable-threads=posix --
enable-checking=release --with-system-zlib --enable-__cxa_atexit --
disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c+
+,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-
plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --
enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/
usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-
linux
Thread model: posix
gcc version 4.1.2 20070502 (Red Hat 4.1.2-12)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: diener896092_no_spam_here@bellsouth.net (Edward Diener)
Date: Sun, 12 Aug 2007 15:14:37 GMT Raw View
tonytinker2000@yahoo.com wrote:
> Please read past this first part. I promise this is about C++.
>
> In C# you can create properties within a class something like this:
>
> class A
> {
> public int Count
> {
> get { return count; }
> set { count = value; }
> }
> private int count;
> }
>
> Given a reference to an "A" object called "a", the property allows the
> "count" member to be accessed as:
>
> a.Count = 5;
> a.Count = a.Count + 5;
>
> There is some interest in providing a similar mechanism for use with C
> ++. There are several articles on the net explaining how to provide
> this functionality. Unfortunately, all of the mechanisms that I looked
> at add overhead to the class for each property defined. Since this is
> primarily syntactic-sugar after all, IMHO adding overhead to support
> this sort of thing is unacceptable.
I do not agree with the last argument. Even if one adds something which
is syntactic sugar, ie. makes it clearer to use a programming construct
while adding no new functionality, the idea that this must somehow
provide zero-overhead is not an acceptable position in my mind.
Whenever some feature is added to the language, via a language change or
library addition, the zero-overhead argument is only valid if it applies
to those NOT using the feature being penalized with added overhead. I
see nothing wrong with adding something to C++, even in the form of
syntactic sugar, which adds overhead only if used.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: xreborner@gmail.com
Date: Sun, 12 Aug 2007 10:15:25 CST Raw View
On Aug 12, 2:48 pm, Pedro Lamar o <pedro.lama...@gmail.com> wrote:
> On 11 ago, 11:38, xrebor...@gmail.com wrote:
>
> > tonytinker's approach is very difficult to use. Too many redundant
> > code is required.
>
> > Properties can be simulated by inner classes. Terminator and Falk have
> > given the sample code. However, these approaches add an overhead for
> > each property for each object, since each inner object must hold a
> > pointer to the outer object.
>
> > I have an idea to simulate properties in c++ without overhead:
>
> Your approach gives me overhead, as follows.
>
> [pedro@localhost Projetos]$ cat hm.cpp
> #include <iostream>
>
> struct type
> {
> public:
> struct
> {
> operator int() const
> {
> return ((type*)(((char*)this)-(char*)((type*)0)->Value))->Value;
> }
> const int& operator=(int X)
> {
> return ((type*)(((char*)this)-(char*)((type*)0)->Value))->Value
> = X;
> }
> } value;
> private:
> int Value;
>
> };
>
> int
> main (int argc, char* argv[]) {
> std::cout << sizeof(type) << std::endl;
> return 0;
>
> }
>
> [pedro@localhost Projetos]$ g++ hm.cpp -o hm
> hm.cpp: In member function 'type::<anonymous struct>::operator int()
> const':
> hm.cpp:10: warning: invalid access to non-static data member
> 'type::Value' of NULL object
> hm.cpp:10: warning: (perhaps the 'offsetof' macro was used
> incorrectly)
> hm.cpp: In member function 'const int& type::<anonymous
> struct>::operator=(int)':
> hm.cpp:14: warning: invalid access to non-static data member
> 'type::Value' of NULL object
> hm.cpp:14: warning: (perhaps the 'offsetof' macro was used
> incorrectly)
> [pedro@localhost Projetos]$ ./hm
> 8
> [pedro@localhost Projetos]$ g++ -v
> Using built-in specs.
> Target: i386-redhat-linux
> Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
> infodir=/usr/share/info --enable-shared --enable-threads=posix --
> enable-checking=release --with-system-zlib --enable-__cxa_atexit --
> disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c+
> +,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-
> plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --
> enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/
> usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-
> linux
> Thread model: posix
> gcc version 4.1.2 20070502 (Red Hat 4.1.2-12)
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html ]
Yes. I just forgot that an empty struct has at least one byte size. I
think this overhead is very little.
If there are many properties, we can put all the properties into one
unnamed union, so that the overhead is still totall one byte.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]