Sign in to follow this  

funny const_cast

This topic is 4862 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Quote:
Isn't that cute,but it's wrong!
#include "stdafx.h"
#include<iostream>
int main(int argc, char* argv[])
{
  const int i = 0;
  int*  j  = const_cast< int*>(&i); 

 *j=13;

std::cout<<i<<"\t"<<*j<<std::endl;	
std::cout<<&i<<"\t"<<j<<std::endl;
 
	return 0;
}


-i and j end up with the same value (13)according to the debugger but watch what the printing statements say(i=0,*j=13 while having the same addresses).
Quote:
Don't count on the smooth compilation!

Share this post


Link to post
Share on other sites
This might be because the compiler will replace all instances of i with the value it is defined as. The value change you perform through j only occurs afterward, at runtime.

I wonder what would happen if, instead of being a local const variable, i was a const argument to the function (ie its value not known by the compiler)?

Share this post


Link to post
Share on other sites
const_cast cannot be used to un-const true constants, but only originally non-const variables which happen to have received a const qualifier at some point, e.g. when passed as function parameters, or return values.

On non-uniform memory architectures, const/volatile variables may not even live in the same place as unqualified variables do, and the cast might cause the compiler to look in the wrong place.

A cast tells the compiler you know what you're doing -- make sure you do. [smile]

Share this post


Link to post
Share on other sites
hi :)
Quote:
const_cast cannot be used to un-const true constants, but only originally non-const variables which happen to have received a const qualifier at some point, e.g. when passed as function parameters, or return values.


what do you mean by true constants and "happen to have received a const qualifier at some point"? can you explain that? could you give an example please because i don't get your point?

thanks

Share this post


Link to post
Share on other sites
A true constant is something that is a constant everywhere. Declaring a variable as const makes it a true constant. The compiler will replace all appearances of that variable by its value, so the variable will not appear in the executable.

A false constant is an object that originally wasn't a constant, but was made constant for the purposes of something. For instance, you have an object that is not constant, and want to extract information from that object. You also want to pass the object by reference, so it is faster (than having to copy it to pass it by value). The problem is, you don't want the object to be modified by the function. So you tell the function the object must remain constant. You do this by specifying the argument of the function as being const. The argument will not be a true constant, since it actually is a real, non-constant object somewhere else in the code. However, for all the purposes of the function, it will be considered as a constant object (ie read-only).

const_cast is used to access certain properties of the object that would otherwise be unavailable if the object was const. An example of this is a const map, where operator [] is not available. If you *know* operator[] will not insert an object into the map (because the object is there), you could un-const it and access it through [].

(Yes, in this case, you'd better off using find)

Quote:

Thanks funny!


He's sooo going to like this :)

Share this post


Link to post
Share on other sites
:'( i don't get it

can you post some code to help me? or a reference that will say about this thing? i serached and found nothing ( except from the following ) :(

why are we able to unconst the "this" pointer inside a member function? isn't that a real const?

Share this post


Link to post
Share on other sites

#include <iostream>
using namespace std;

//we declare a function that takes as argument
//an integer it is not allowed to modify
int divide( const & int );

void main( void ) {
const int true_const = 18;
int false_const = 1337;

//true_const is a constant, it will not exist in the executable
//the following line:

cout << true_const << endl;

//will be replaced by cout << 18 << endl; by the compiler
//false const is a variable, you can modify it:

false_const = 123456;

//and now we apply divide to false const
int result = divide( false_const );

cout << result << endl;
}

int divide( const & int const_here ) {

//const_here is a constant in this function,
//although it can be nonconstant in another function.

const_here = 3; //throws an error

//however, we can read it, just like a real const.

return const_here / 18;
}





false_const becomes const_here when we apply divide( ) to it: it becomes constant in the function, but can be modified somewhere else in the code.

EDIT: don't be so impatient. I just woke up!

Share this post


Link to post
Share on other sites
int * not_const_anymore = const_cast<int*>( &const_here );

You can now modify the integer *not_const_anymore, which is not const. Also, *not_const_anymore is, in fact, the variable const_here (they have the same address).

BUT, const_cast should *not* be used to modify the value of a variable! When you pass a variable as a const to a function, you do it because you expect the variable not to be modified, so if the function actually modifies the variable, you run the risk of the program not doing what you want. Imagine a program like:

for(int i = 0; i < 10; ++i) { do_something( i ); }

where do_something( const int ) actually modifies the integer by substracting 1 from it.

What you can use it, however, is when you *know* a given function will not modify the variable, BUT does not treat the variable as const. This can happen when using third party code, where no "const" version of function exists. You may have to convert your const back to non-const to be able to apply these functions.

Share this post


Link to post
Share on other sites
ok thanks i get it :)

but can you tell me why this prints 6? Isn't it a true constant?

#include <iostream>
using namespace std;

void divide( const int & );

void test( const int con )
{
divide( con );
cout << con << endl;
}

void main()
{
test(12);
}


void divide( const int &const_here )
{
int *a = const_cast<int*>(&const_here);
*a = 6;
}

Share this post


Link to post
Share on other sites
It prints 6 because it's not a true constant:

void test( const int con )

the absence of a & before the variable name means the variable will be passed by value: a new variable is created, called "con", and given the value of the argument. This is a false constant, however (because its value is not always the same: it depends on the variable that is passed to the function).

As a rule of thumb, a constant is true if it defined using the syntax:

const int x = 0;

Passing a true constant by reference to a function, and modifying it, is undefined behavior. Anything can happen, what happens depends on the compiler, the target system and the position of the moon. There's no explaining to it, because these things are not meant to be done.

Share this post


Link to post
Share on other sites

This topic is 4862 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this