Two questions about const modifier

A

Allen

1. why can not static member function be declared as const?

class Demo
{
public:
static int method() const; // error!!
};

2. is this kind of const_cast usage secure?

class Demo
{
public:
static const int VALUE = 12;

void Read(int* pValue, int offset)
{
if (offset < 0 || offset >= 2)
return;
value[offset] = *pValue;
}

private:
int value[2];
};

int main()
{
int val1 = 0, val4 = Demo::VALUE;
Demo demo;
demo.Read(&val1, 0); // absolutely ok
demo.Read(const_cast<int*>(&val2), 1); // is const_cast secure here?
}
 
A

Allen

int main()
{
int val1 = 0, val4 = Demo::VALUE;
Demo demo;
demo.Read(&val1, 0); // absolutely ok
demo.Read(const_cast<int*>(&val2), 1); // is const_cast secure here?

}

Sorry, main method should be:

int main()
{
int val1 = 0, val4 = Demo::VALUE;
Demo demo;
demo.Read(&val1, 0); // absolutely ok
demo.Read(const_cast<int*>(&Demo::VALUE), 1); // is const_cast secure
here?
demo.Read(&val2, 1); // use this?
}
 
N

Noah Roberts

Allen said:
1. why can not static member function be declared as const?

class Demo
{
public:
static int method() const; // error!!
};

Because a const function means that the function will not change the
instance it is called on. Static functions have no instance so can't
exactly change it...it just plain makes no sense for them to be const
as it's meaningless.
 
N

Noah Roberts

Allen said:
Sorry, main method should be:

int main()
{
int val1 = 0, val4 = Demo::VALUE;
Demo demo;
demo.Read(&val1, 0); // absolutely ok
demo.Read(const_cast<int*>(&Demo::VALUE), 1); // is const_cast secure
here?

Absolutely not.
 
A

Allen

Absolutely not.

So need to write like this?

int main()
{
int val1 = 0, val4 = Demo::VALUE;
Demo demo;
demo.Read(&val1, 0);
demo.Read(&val2, 1);
return 0;
}

why is not secure to use const_cast for static const member address?
 
A

Allen

Absolutely not.

So need to write like this?

int main()
{
int val1 = 0, val2 = Demo::VALUE;
Demo demo;
demo.Read(&val1, 0);
demo.Read(&val2, 1);
return 0;
}

why is not secure to use const_cast for static const member address?
 
N

Noah Roberts

Allen said:
So need to write like this?

int main()
{
int val1 = 0, val4 = Demo::VALUE;
Demo demo;
demo.Read(&val1, 0);
demo.Read(&val2, 1);
return 0;
}

This won't work either because val2 doesn't exist.
why is not secure to use const_cast for static const member address?

Because modification of a const object causes undefined behavior. In
your case, a static integer constant, that variable may not even exist
in the final executable. Taking the address of course changes that but
it may still be in a location of memory that is considered unwritable
and can cause crashes or whatever.

The cast itself isn't the problem. It is the assumption that by doing
the cast you plan on writing to that location in memory.
 
A

Allen

"Noah Roberts дµÀ£º
The cast itself isn't the problem. It is the assumption that by doing
the cast you plan on writing to that location in memory.

In fact, I use the static const address to READ value, not WRITE.

value[offset] = *pValue; // pValue point to Demo::VALUE

But, according to you, it is sure not secure because the integer may
not
exist in the excutable file.

Thanks.
 
A

Allen

One more question about const.

INT32 CFileLogger::Output(const COutLogMesg& logMesg)
{
fstream fs;
fs.open(CLogger::GetLogFile(), ios::in | ios::eek:ut);

if (!fs.good())
{
return 0;
}

CHAR szBuf[512];
INT32 nLength = const_cast<COutLogMesg&>(logMesg).FormatMesg(szBuf,
512);
if (nLength <= 0)
{
...
}
}

I want to pass reference to Output method and limit it not to be
changed. If I the above line
to be
INT32 nLength = logMesg.FormatMesg(szBuf, 512);
The compiler will tell an error saying that
'COutLogMesg::FormatMesg' : cannot convert 'this' pointer from 'const
COutLogMesg' to 'COutLogMesg &'

Why?
 
M

Micah Cowan

Allen said:
"Noah Roberts дµÀ£º
The cast itself isn't the problem. It is the assumption that by doing
the cast you plan on writing to that location in memory.

In fact, I use the static const address to READ value, not WRITE.

value[offset] = *pValue; // pValue point to Demo::VALUE

But, according to you, it is sure not secure because the integer may
not
exist in the excutable file.

Actually, he already pointed out that taking its address forces it to
exist (so I'm not sure what his point was, exactly). I suspect he
misread the code and believed you were writing to the value.

The const_cast<> is actually valid, so long as you don't try to write
to it.

I suppose you already know that Read() is poorly written, though, and
since it doesn't modify its argument, would've been much better
specified as Read(const int *pValue, int value), in which case no
const_cast<> would ever have been necessary.
 
I

IR

Allen said:
"Noah Roberts дµÀ£º
The cast itself isn't the problem. It is the assumption that by
doing the cast you plan on writing to that location in memory.

In fact, I use the static const address to READ value, not WRITE.

value[offset] = *pValue; // pValue point to Demo::VALUE

But, according to you, it is sure not secure because the integer
may not
exist in the excutable file.

As Noah said, casting the const away implies that you intend
modifying it. The problem has nothing to do with the existence of
the variable in the resulting binary file.


There are very few legitimate uses of casts in C++. Unless you
really know what you are doing, using a cast generally means that
there is a design problem elsewhere.

Casting is like saying to the compiler: "Get away from my code I
don't need you anymore, you picky language enforcer". And most of
the time this is a Very Bad Thing.


If you don't modify the value in your function, why not declare a
pointer to const in the first place?

void Read(const int* pValue, int offset)

This way, you don't have to cast Demo::VALUE's constness away, and
just reading Read() declaration allows anyone to know that *pValue
will NEVER be modified inside the function. Moreover, if you
accidentally try to modify *pValue, the compiler will yell at you,
which is a good thing.


Cheers,
 
N

Noah Roberts

Allen said:
"Noah Roberts дµÀ£º
The cast itself isn't the problem. It is the assumption that by doing
the cast you plan on writing to that location in memory.

In fact, I use the static const address to READ value, not WRITE.

value[offset] = *pValue; // pValue point to Demo::VALUE

In that case the parameter should be const and then there is no
problem.

Another very important reason why this type of code is not "secure" is
that it removes safety. Imagine that at some point Read is modified is
such a way that it now modifies it's parameters. This would be a
natural thing to do for a maintainer since the parameters are not const
so obviously nobody is going to call Read with a const object...

The compiler will never complain because someone used a const_cast to
get it to shut up about the const parameter. Undefined behavior will
be introduced and might very well only show up in certain obscure
situations many months after anyone has touched any of the code related
to the problem.

No, the use of const_cast in that way in insecure in that it removes
security features and leaves you at the mercy of fate.
 
G

Gavin Deane

Noah said:
No, the use of const_cast in that way in insecure in that it removes
security features and leaves you at the mercy of fate.

Note that one of the big benefits of const_cast exisiting is that if
you are faced with a legacy API that does not declare parameters const
when it should (i.e. when the function in question really does not
modify the variable passed to it), you can use const correctly
throughout your own code and use const_cast to stop the
const-incorrectness propogating outside the API into your own code.

That doesn't seem to be the case here because the OP can simply modify
the called function to have a const-correct signature. But when you
don't have that option, using const_cast in the way described in this
thread is exactly the thing to do.

Gavin Deane
 
N

Noah Roberts

Gavin said:
Note that one of the big benefits of const_cast exisiting is that if
you are faced with a legacy API that does not declare parameters const
when it should (i.e. when the function in question really does not
modify the variable passed to it), you can use const correctly
throughout your own code and use const_cast to stop the
const-incorrectness propogating outside the API into your own code.

That doesn't seem to be the case here because the OP can simply modify
the called function to have a const-correct signature. But when you
don't have that option, using const_cast in the way described in this
thread is exactly the thing to do.

Yes, sometimes it is a necissary evil but it is never "secure".
 

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,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top