Re: Simple question on Pointers
- From: "Alan Carre" <alan@xxxxxxxxxxxxxxxxx>
- Date: Wed, 3 Dec 2008 22:37:22 +0700
"Igor Tandetnik" <itandetnik@xxxxxxxx> wrote in message
news:%23NuyQwUVJHA.2512@xxxxxxxxxxxxxxxxxxxxxxx
"Alan Carre" <alan@xxxxxxxxxxxxxxxxx> wrote in message
news:u$aTCYUVJHA.3796@xxxxxxxxxxxxxxxxxxxx
int SomeClass::Member() const
{
if(m_bFirstTimeThrough)
{
((SomeClass*)this)->m_iMember = InitMember();
((SomeClass*)this)->m_bFirstTimeThrough = false;
}
Such a member is, of course, bad idea. If called on an object declared as
const SomeClass, this method exhibits undefined behavior, but you won't
get any compiler errors.
Such a member may be a bad idea, but it may be the only way to get around
"one-time initialization" where a lengthy / costly operation has to be
performed, but only if the user of the class requires access to this
particular bit of information, otherwise the calculation can be
ignored/postponed.
An off-hand example might be a class where the contents are stored
(minimally) as a file name (contents being encrypted data for example), and
the user wishes to extract the string data corresponding to the file
(decrypted). If the file were quite large (let's say a 100K or so), and you
had a few thousand such objects you would not want to perform this
calculation for every single object immediately, you'd only want to do that
when recieving a request for the file's contents. Now suppose the decryption
method takes several minutes to complete (even after grabbing the data from
disk), then clearly it would further be desireable to save off the decrypted
data within the class for future reference (it's coupled to the file so
where else would it go?), particularly if you intended to pass the object
(as a const&) to other functions or classes. Note: decryption doesn't have
to mean security! it could mean re-interpretation, or disassembly etc. So no
need to get into any of this "that's a security hole" garbage.
Now you say that the above is a bad idea, so I would like to know how you'd
accomplish the above task when given a "const&" to an object of this type?
Or would you say this object is inherently non-const hence we must expose
it's modifiers to the whole world? Or would you choose to have your program
run so sluggish that it would essentially become unusable? I think both of
those alternatives are particularly "bad ideas". Perhaps you'd create some
kind of link between the object and it's data via. a global map or
something... perhaps adding more sluggishness. And now we'll need to start
to count references to it and add in more globals to manage the map etc etc
etc... good idea? Wouldn't it be nice if an object contained it's own data?
struct SomeClass;
SomeClass* global = NULL;
struct SomeClass {
SomeClass() : m_iMember(0) {}
void foo() const {
cout << m_iMember << endl;
cout << Member() << endl;
cout << m_iMember << endl;
}
int Member() {
if (global) global->m_iMember = 42;
return m_iMember;
}
Yes, I understand that it is possible to modify the contents of a class via
such tricks and hacks which are *lies to the compiler*, and *bugs to the
user*. However isn't the optimizer is under no obligation to disagree with
your completely unambiguous declaration that m_iMember is, in fact, constant
during the scope of the function? Unless there is such an obligation that I
am unaware of...
Does the C++ standard say anything about how the optimizer should accomplish
it's task in light of the fact that people can write buggy code, or code
that has undefined behaviour? You're the expert on the standard so I will
defer to you on that question.
I can write a program that solves any problem in under 1ms - provided the
solution doesn't have to actually be correct.
Actually it's possible to write programs that give correct answers as well.
If all the functions involved are inline, and the optimizer can see
through them and confirm that no funny business with casts or aliasing is
going on, then it can hoist the variable into the register. Presumably, in
a tight inner loop where you are so concerned about performance that an
extra memory read is a problem, you would use inline functions.
*An* issue was given, namely memory access (I don't know why you emphasize
"so concerned") from register vs. memory. That's ONE possible concern
someone might have depending on their needs. For instance, go and rewrite
msoft's _isnan to examine only the *relevant* bits of a double and thereby
double (as in twice) the function's speed. That change caused a 3% increase
in speed for a particularly computationally-intensive program that I know of
(yes the same friend, same company); if a program performs trillions of
floating point calculations every second, a 3% increase in speed is quite a
substantial increase in the number of FP-OPS done per second. And judging by
the bonus awarded for it (trust me, you don't even want to know...) can be
highly valued by certain people.
Perhaps there's a way to change the design of the class so that a method
declared const doesn't need to modify the object in the first place?
Perhaps. But that question was never put.
In any case, casts are a red herring here. If Member() is opaque to the
optimizer, it has to assume that m_iMember may change through aliasing, as
shown above. If Member is inline, then yes, the optimizer can rewrite
foo() e.g. like this:
void foo() const {
register int iMember = m_iMember;
cout << iMember << endl;
if(m_bFirstTimeThrough)
{
iMember = ((SomeClass*)this)->m_iMember = InitMember();
((SomeClass*)this)->m_bFirstTimeThrough = false;
}
cout << iMember << endl;
cout << iMember << endl;
}
Oh is that what you meant... I read from top to bottom... so I deleted
something above. Well ok then, that's probably a good aproach in such cases.
I'd be curious to know about that, and also whether or not the OP's
question even applies to this case.
You mean, Robby's question about pointers and arrays? We are nowhere near
that by now.
No, I meant the OP for this specific sub-thread, namely "Cezary Noweta". I
was too lazy to look it up at the time.
- Alan Carre
.
- Follow-Ups:
- Re: Simple question on Pointers
- From: Igor Tandetnik
- Re: Simple question on Pointers
- From: Cezary H. Noweta
- Re: Simple question on Pointers
- References:
- Re: Simple question on Pointers
- From: Ben Voigt [C++ MVP]
- Re: Simple question on Pointers
- From: Cezary H. Noweta
- Re: Simple question on Pointers
- From: Igor Tandetnik
- Re: Simple question on Pointers
- From: Doug Harrison [MVP]
- Re: Simple question on Pointers
- From: Igor Tandetnik
- Re: Simple question on Pointers
- From: Doug Harrison [MVP]
- Re: Simple question on Pointers
- From: Alan Carre
- Re: Simple question on Pointers
- From: Igor Tandetnik
- Re: Simple question on Pointers
- Prev by Date: Re: Simple question on Pointers
- Next by Date: Re: Simple question on Pointers
- Previous by thread: Re: Simple question on Pointers
- Next by thread: Re: Simple question on Pointers
- Index(es):
Relevant Pages
|