473,847 Members | 1,522 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Accessing private member of a class through type-casting

Consider the code

class A {
private:
int a;
};

int main(void) {
A x;
int* ptr = (int*)&x;
*x = 10;
return 0;
}

I understand that I can not change the private attributes of a class,
but what does standard have to say about the code above?

Apr 7 '06
31 3205
dragoncoder wrote:
If I correct the code so that *x = 10 becomes *ptr = 10, even then is
the behaviour undefined ?
Yes.
I want to know which step I am doing wrong ? Is it illegal to assign
(int*)&x to ptr ? Or is it illegal to do *ptr = 10 ? I am confused.


It is illegal to use 'ptr' after obtaining it by reinterpret_cas t'ing
it from '&x'. The Standard says that if two pointers are unrelated (and
they are), all you can do with the pointer is to cast it back and get
the same pointer value iff the alignment requirements are no less strict
for the destination ("temporary" ) pointer. Something like that, anyway.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 7 '06 #11

Victor Bazarov wrote:
dragoncoder wrote:
If I correct the code so that *x = 10 becomes *ptr = 10, even then is
the behaviour undefined ?


Yes.
I want to know which step I am doing wrong ? Is it illegal to assign
(int*)&x to ptr ? Or is it illegal to do *ptr = 10 ? I am confused.


It is illegal to use 'ptr' after obtaining it by reinterpret_cas t'ing
it from '&x'.


The result is undefined...it is not illegal to do so.

Apr 7 '06 #12

dragoncoder wrote:
If I correct the code so that *x = 10 becomes *ptr = 10, even then is
the behaviour undefined ?


It becomes undefined. *x = 10 is illegal and won't compile.

Apr 7 '06 #13
dragoncoder wrote:
int* ptr = (int*)&x;
*ptr = 10;


Let me try to explain the illegality.

(int*) in C is the same as reinterpret_cas t<> in C++. C++ only defines the
result of such a cast if it casts a pointer to what the data really is.

Such typecasts make the compiler pretend that a class A is an int. This
would be legal:

A * p = (A *)(int *) &x; // both could use reinterpret_cas t

Your code might do anything (including appear to work correctly) because you
don't know if the address of A::a is the same as the address of its A. So
your cast might not end up pointing to an int.

Your code will most likely appear to work, because a compiler has no reason
to put any other data in A except the int a. Because the behavior is
undefined, it might break if you change something about your compiler, or
class A. For example, if you add a virtual destructor, your code will most
likely fail.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 7 '06 #14
Phlip posted:
dragoncoder wrote:
int* ptr = (int*)&x; *ptr = 10;
Let me try to explain the illegality.

(int*) in C is the same as reinterpret_cas t<> in C++.

Not really. "reinterpret_ca st" can't cast pointers to functions if I recall
correctly, while C-style casts can.
C++ only defines
the result of such a cast if it casts a pointer to what the data really
is.

Such typecasts make the compiler pretend that a class A is an int. This
would be legal:

A * p = (A *)(int *) &x; // both could use reinterpret_cas t

I don't think this should work. The two types, "A*" and "int*" are
unrelated. Yes, they are both pointers, but what they point to are totally
different. In three steps, here's what you're doing:

1: Start off with the expression "&x" which is of type "A*".
2: You then use a C-style cast to turn it into an "int*". The Standard
doesn't guarantee that an "int*" can reliably hold the address of an object
of type "A", so the value might get corrupted.
3: Now you use a C-style cast again to turn it into an "A*", but the value
may already have been corrupted.

It's quite like the following:

double k = 32.2342;

double f = (double) (int) k;

f will have the value of 32 rather than 32.2342.

Your code might do anything (including appear to work correctly)
because you don't know if the address of A::a is the same as the
address of its A. So your cast might not end up pointing to an int.

I believe this is true.
-Tomás
Apr 7 '06 #15

Phlip wrote:
dragoncoder wrote:
int* ptr = (int*)&x;
*ptr = 10;


Let me try to explain the illegality.

(int*) in C is the same as reinterpret_cas t<> in C++. C++ only defines the
result of such a cast if it casts a pointer to what the data really is.

Such typecasts make the compiler pretend that a class A is an int. This
would be legal:

A * p = (A *)(int *) &x; // both could use reinterpret_cas t

Your code might do anything (including appear to work correctly) because you
don't know if the address of A::a is the same as the address of its A. So
your cast might not end up pointing to an int.

Your code will most likely appear to work, because a compiler has no reason
to put any other data in A except the int a. Because the behavior is
undefined, it might break if you change something about your compiler, or
class A. For example, if you add a virtual destructor, your code will most
likely fail.


You are explaining undefined behavior. The word "illegal" never
appears in the standard that I know of and at least not in the
definitions section. I would take "illegal" to mean against the
standard, which would equate to ill-formed. Such a cast is not against
the standard. The standard explicitly defines the mapping of such cast
as implementation-defined and that "a pointer to an object can be
explicitly cast to a pointer to an object of a different type." This
means that the cast of A* to int* is _allowed_ by the standard and the
result is /implementation-defined/.

The use of the resulting pointer is as undefined as using any other
random pointer. As such, the standard imposes no requirements
whatsoever so the construct is still not dissallowed or "illegal" by
any definition of the word I know of.

Apr 7 '06 #16
Noah Roberts wrote:
This
means that the cast of A* to int* is allowed by the standard and the
result is implementation-defined.


I'm aware, in our culture, that "illegal" does not necessarily mean "you
shouldn't do it".

class A {
public:
A() { assert((int)thi s == (int)&a); }
private:
Â*Â*intÂ*a;
};

There. If that assertion would pass, then the cast is "legal". And note that
"legal" also does not appear in The Standard, yack yack yack, etc.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 7 '06 #17

Tomás wrote:
Phlip posted:
dragoncoder wrote:
int* ptr = (int*)&x; *ptr = 10;
Let me try to explain the illegality.

(int*) in C is the same as reinterpret_cas t<> in C++.

Not really. "reinterpret_ca st" can't cast pointers to functions if I recall
correctly, while C-style casts can.


See 5.2.10. P4 states you can convert a pointer to an int. P5 states
you can convert a function pointer to another function pointer.
C++ only defines
the result of such a cast if it casts a pointer to what the data really
is.

Such typecasts make the compiler pretend that a class A is an int. This
would be legal:

A * p = (A *)(int *) &x; // both could use reinterpret_cas t

I don't think this should work. The two types, "A*" and "int*" are
unrelated. Yes, they are both pointers, but what they point to are totally
different.


The behavior of the above expression is actually well defined. Given
certain requirements the result is the same as &x. Failing to meet
those requirements has "unspecifie d" results.

In three steps, here's what you're doing:
1: Start off with the expression "&x" which is of type "A*".
2: You then use a C-style cast to turn it into an "int*". The Standard
doesn't guarantee that an "int*" can reliably hold the address of an object
of type "A", so the value might get corrupted.
3: Now you use a C-style cast again to turn it into an "A*", but the value
may already have been corrupted.

It's quite like the following:

double k = 32.2342;

double f = (double) (int) k;

f will have the value of 32 rather than 32.2342.


Actually, it is nothing like that. double and int have well defined
conversions. That particular C-style cast is the same as two
static_cast operations. The previous is two reinterpret_cas t
operations. Totally different casts...again, this is the problem with
c-style casting...they look the same but are not.

Apr 7 '06 #18
Noah Roberts wrote:
double k = 32.2342;

double f = (double) (int) k;

f will have the value of 32 rather than 32.2342.


Actually, it is nothing like that.Â*Â*double Â*andÂ*intÂ*hav eÂ*wellÂ*define d
conversions


Let's try "well defined _lossy_ conversions".

I'm beginning to suspect (because you read The Standard for me), that
pointer conversions are well-defined as lossless.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 7 '06 #19

Phlip wrote:
Noah Roberts wrote:
This
means that the cast of A* to int* is allowed by the standard and the
result is implementation-defined.


I'm aware, in our culture, that "illegal" does not necessarily mean "you
shouldn't do it".


The word illegal has a well defined definition in the English language,
let us look to it:

1. Prohibited by law.
2. Prohibited by official rules: an illegal pass in football.
3. Unacceptable to or not performable by a computer: an illegal
operation.

#1 does not apply - law in this case being the standard.
#2 also similarly to #1 does not apply.

The standard _allows_ the cast so by elimination it is not prohibited
;)

#3 is the only possibilty however since the operation IS performable I
don't see how it applies.

The standard _allows_ the cast...all implementations therefore have to
allow it and be able to perform it. The standard does not specify how.

So, you can redefine words if you wish but then you may as well be
speaking in Greek...or Martian for that matter.

Apr 7 '06 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
2420
by: Sandeep | last post by:
Hi, In the following code, I wonder how a private member of the class is being accessed. The code compiles well in Visual Studio 6.0. class Sample { private: int x; public:
2
2318
by: Steven T. Hatton | last post by:
I find the surprising. If I derive Rectangle from Point, I can access the members of Point inherited by Rectangle _IF_ they are actually members of a Rectangle. If I have a member of type Point in Rectangle, the compiler tells me Point::x is protected. I would have expected Rectangle to see the protected members of any Point. Compiling the following code give me this error: g++ -o rectangle main.cc main.cc: In member function `size_t...
4
5751
by: Tom | last post by:
Let's say I've got a class defined in a header file. class foo { private: ... int bar; .... }; Now lets say I have a function that needs to access the private variable
4
3040
by: ambar.shome | last post by:
Hi, Please take a look at the code snippet given below:#include<iostream> using namespace std; class A { public: virtual void test(){cout<<"Default implementation called"<<endl;}
8
2749
by: dwok | last post by:
I have been wondering this for a while now. Suppose I have a class that contains some private member variables. How should I access the variables throughout the class? Should I use properties that expose the variables or is it OK to just access the variables directly? Keep in mind that I am talking about accessing the variables from within the class that they are defined. Thanks!
23
2615
by: Ben Voigt | last post by:
I have a POD type with a private destructor. There are a whole hierarchy of derived POD types, all meant to be freed using a public member function Destroy in the base class. I get warning C4624. I read the description, decided that it's exactly what I want, and ignored the warning. Now I'm trying to inherit using a template. Instead of "destructor could not be generated because a base class destructor is inaccessible", I now have an...
6
5037
by: earthwormgaz | last post by:
Is the following legal? class Outer { class Inner { private: Inner() { } };
2
2604
by: mickey22 | last post by:
Hi all, I have some data members and member functions that are declared as private in a class A. Now I want to use these data members and functions(which are private) in my new C++ source file(.cpp file).I have created pointer to this class A, and tried to use the functions but I am getting an errror that: cannot access private data member. Could anyone please help me with this?Thanks Example : ///abc.cpp file (my source file)
6
1569
by: smoermeli | last post by:
#include <iostream> #include <vector> class Thing { private: int value; friend class Person; public: int getValue() { return value; } void setValue(const int val) { value=val; }
2
1611
by: agendum97 | last post by:
Is there a way of constructing a "class" in JavaScript to access a private member of a different scope of the same type? It is important that the variable remain private, and not accessible in anyway publically. For example: function SomeObj(privateKey) { this.process = function(someObj) { if (!(someObj instanceof SomeObj))
0
9892
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9735
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10996
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10658
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10347
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9497
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
7062
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5730
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
3
3171
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.