Try to modify const reference - c++

I've got an argument with my co-workers.
Once I did try to modify constant reference.
Sample of code is below:
#include <cstdio>
#include <cstdlib>
using namespace std;
int main(int argc, char const *argv[])
{
const int* A = NULL;
printf("A = %p\n", A);
int** pA = const_cast<int**>(&A);
*pA = new int(5);
if (pA != NULL)
printf("pA = %p, value = %d\n", pA, *pA);
else
printf("pA null pointer\n");
if (A != NULL)
printf("A = %p, value = %d\n", A, *A);
else
printf("A null pointer\n");
return 0;
}
Everything works fine and the log is
A = 00000000
pA = 0028FED8, value = 4068760
A = 003E1598, value = 5
I think it works that way:
I create a const pointer variable A with '0' (zero) value is stack. It is local variable wich occupies 4 bytes of memory in stack.
then I create a pointer to pointer variable, I cast away constant modification and take address of the variable
I think this code works fine and will not lead to a bug. But I need some kind of explanations. Am I right?

const int *a and int * const a are different.
Case 1
[const is used on *a]
Here the value of a is constant. The address pointed by a can be changed.
const int *a = malloc(sizeof (int));
if (a)
{
//*a = 10; //not allowed
a = malloc(sizeof (int));; //allowed
}
Case 2
[const is used on a]
Here the address of a is constant. The value of a can be changed.
int * const a = malloc(sizeof (int));
if (a)
{
*a = 10; //allowed
//a = malloc(sizeof (int));; //not allowed
}
EDIT:
As suggested by #lifeOfPI, read about using const_cast .

Related

Are double pointers necessary?

void test(int *p2) {
*p2 = 3;}
int main()
{
int* p1, x = 5;
p1 = &x;
test(p1); // p1 and p2 are pointing to the same address which is x's address
printf("%d", x); //prints 3
this example 2 pointers pointing to the same address, which passing to the function by reference.
Now take this 2nd example
void test(int **p2) {
**p2 = 3;
}
int main()
{
int* p1, x = 5;
p1 = &x;
test(&p1); // p2 is pointing to p1 address
printf("%d", x);
so are double pointers necessary in these type of situations? especially with structured linked lists?
typedef struct NOde {
int data;
struct NOde* next;
}node;
void test(node *head) {
node* new_node = (node*)malloc(sizeof(node));
new_node->data = 5;
new_node->next = head;
head= new_node;
}
int main()
{
node* head=NULL;
test(head);
and why in this one, the head values in the main still NULL if it same concept as above?
Pointers (*p) are sufficient when you want to change the contents of the address the pointer is pointing at.
Double star pointers (**p) are necessary when you want to change the address the pointer is pointing at.
In the following code, inspect the outcome of the second printf statements especially.
#include <stdio.h>
#include <stdlib.h>
void swapValues(int *p, int val) {
*p = val;
}
void swapPointers(int **p, int *val) {
*p = val;
}
int main() {
int x, y;
int *p1 = &x;
int *p2 = &x;
x = 3;
y = 5;
printf("x = %d y = %d p1 = %d p2 = %d\n", x, y, *p1, *p2);
printf("p1 = %p p2 = %p\n", p1, p2);
swapValues(p1, y);
printf("x = %d y = %d p1 = %d p2 = %d\n", x, y, *p1, *p2);
printf("p1 = %p p2 = %p\n", p1, p2);
x = 3;
y = 5;
swapPointers(&p2, &y);
printf("x = %d y = %d p1 = %d p2 = %d\n", x, y, *p1, *p2);
printf("p1 = %p p2 = %p\n", p1, p2); // observe value of p2 here
return 0;
}
In C, all function calls are made by value. Which essentially means that the called function always gets its own copy of the arguments you pass to it. Same goes with the value you return from the function. There is always a copy of this value given back to the caller. The moment a function finishes execution, all arguments passed to it and local variables declared within it cease to exist.
For example:
int add(int a, int b)
{
int result = a + b;
return result;
}
int main()
{
int p = 3, q = 5;
int r = add(p,q);
}
In this case, a and b are copies of p and q respectively, and r is a copy of result. p, q and result no longer exist after add() has finished execution.
Now, this is fine for many common use-cases as in the example above. But what if you want to change the value of one of the variables in the calling function from within the called function? You then need to pass the address of the variable, so that the called function can indirectly access the variable in the calling function and update it.
Example:
void inc(int *p)
{
*p = *p + 1;
}
int main()
{
int a = 5;
inc(&a);
}
In this case, the called function gets a copy of the address of a, called p, using which it is able to update the memory location holding a indirectly. This is called dereferencing a pointer.
Now, to address your question, we need to take this one step further - what if we need to update a pointer in the calling function? We need to pass a pointer to the pointer - also called a double pointer.
In your example, we need to update head, which is already a pointer to a Node. So we need to pass the address of head, for which we need a double pointer.
Hence your code should be:
void test(node **phead)
{
node* new_node = (node*)malloc(sizeof(node));
new_node->data = 5;
new_node->next = *phead;
/* Note the dereferencing here - we update `head` indirectly through a pointer */
*phead = new_node;
}
test(&head);
Otherwise, we would be passing around a copy of head, which is a pointer, using which you can access the node that head points to, but not head itself. If you increment this pointer within your function, the change is not reflected outside, because this copy ceases to exist the moment the function returns.
PS: C++, unlike C, supports call by reference, which means the language transparently handles the pointer management and lets you directly update variables passed to you 'by reference'.
In your case no, because to assign the value you only need one pointer.
void test(int *p2) {
*p2 = 3;
}
Pointers to pointers are useful when you want to change the pointer.
A common use of pointers to pointers is methods that create something, but want to return something other than the pointer itself, e.g.
myerror_t create_foo(foo_t **p, int a, int b, int c)
{
if (a < 0 || b < c) return MYERR_INVALID_ARG;
*p = malloc(sizeof foo_t);
p->x = a * b * c;
return MYERR_SUCCESS;
}
Note that in C++, sometimes references are used when changing the value, and they can function in a very similar way.
void test(int &p2) {
p2 = 3;
}
Also note in C++, that throwing an exception, often from a constructor, is more common that a create_foo style method.
Foo::Foo(int a, int b, int c)
{
if (a < 0) throw std::invalid_argument("Foo a < 0");
if (b < c) throw std::invalid_argument("Foo b < c");
x = a * b * c;
}
If a factory function is desired, it might return the pointer and throw exceptions.
double pointers are needed if you are going to change the pointer itself in the function
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int value1 = 10;
int value2 = 20;
void choose(int x, int **pointerToValue)
{
switch(x)
{
case 0:
*pointerToValue = &value1;
break;
case 1:
*pointerToValue = &value2;
break;
default:
*pointerToValue = NULL;
}
}
int main()
{
int *ptr;
int choice;
choose(choice = rand() & 1, &ptr);
//ptr value was changed in the function
printf("Choice = %d, value = %d\n", choice, ptr ? *ptr : 0);
}
Are double pointers necessary?
TL;DR:
The moment a function shall change the value of a pointer defined by the calling function, then yes, they are (and can even become triple, quatuple, ... pointers).
Longish answer:
To have a function change a variable of type T and this variable is defined by the caller, the caller needs to pass to the function a pointer to T, that is a T*.
The function then needs to dereference the T* variable using the * operator as shown in your 1st snippet:
void test(int *p2) {
*p2 = 3; /* p2 is dereferenced, so the assignment works on the variable it is pointing to. */
}
So if then T already is a pointer type then T* would be a pointer to a pointer.
This latter case should be the appearing within the last snippet you show. And it shall be handled exactly as in the 1st snippet. node * head shall be changed within test2(). So pass the address of head;
test2(&head);
To be able to do so the parameter of test2 need to be defined as a pointer to the type of head. head is node*, so a pointer to is is node**.
void test2(node ** phead)
To then change the value of the caller's head inside the function the pointer to head, namely phead needs be dereferenced:
*phead = ....
why in this one, the head values in the main still NULL if it same concept as above?"
Comparing the lines of your last snippet to the versions in my answer, you see that your code in fact is not using the "same concept" but misses a level of indirection, which your 1st snippet indeed uses ...;)
You would only pass a double (or triple, or whatever) pointer to a function if you need the function to write a new pointer value to the parameter, or if you're dealing with multiple-dimensioned data (an array of pointers to arrays (of pointers to arrays of ...)).
If you want a function to write to a parameter of type T, then you need to pass a pointer to T:
void foo( T *p )
{
*p = new_T_value(); // write a new value to the thing p points to
}
void bar( void )
{
T var;
foo( &var ); // foo writes a new value to var
}
Now let's replace T with the pointer type P *:
void foo( P **ptr )
{
*ptr = new_pointer_to_P_value;
}
void bar( void )
{
P *var;
foo( &var ); // write a new pointer value to var
}
Once more for emphasis, replace P with Q *:
void foo( Q ***ptr )
{
*ptr = new_pointer_to_pointer_to_Q_value;
}
void bar( void )
{
Q **var;
foo( &var ); // write a new value to var
}
The semantics are the same in all three cases, all that's changed is the level of indirection. For N levels of indirection in bar, you need N+1 levels of indirection in foo.
The other case for multiple indirection is multiple-dimensioned data (arrays of pointers to arrays of pointers to ...). For example:
void create_2d_arr( int ***arr, size_t rows, size_t cols )
{
*arr = malloc( rows * sizeof *(*arr) );
if ( *arr )
{
for ( size_t i = 0; i < rows; i++ )
{
(*arr)[i] = malloc( cols * sizeof *(*arr)[i] )
{
for ( size_t j = 0; j < cols; j++ )
{
(*arr)[i][j] = initial_value;
}
}
}
}
}
As to your example:
void test(node *head) {
node* new_node = (node*)malloc(sizeof(node));
new_node->data = 5;
new_node->next = head;
head= new_node;
Yes, in this case, if you want the change to head to be seen in main, you have to pass a pointer to the pointer:
void test(node **head) {
node* new_node = (node*)malloc(sizeof(node));
new_node->data = 5;
new_node->next = *head;
*head= new_node;
}
int main( void )
{
...
test( &head );
...
}
It's not necessary double pointer because p2 is in the scope of the function so in the main function is not visibile. And you don't want to change the pointer address but only the value of the pointed variable.
If ypu want to change a variable in a function you should pass it by reference in C or C++ meaning.
Consider your example of a singly-linked list. The variable head has a pointer type.
node* head=NULL;
So to change it in the function test you need to pass the variable by reference. For example
A C implementation passing by reference
void test( node **head, int data )
{
node *new_node = ( node* )malloc( sizeof( node ) );
new_node->data = data;
new_node->next = *head;
*head= new_node;
}
and a C++ implementation passing by reference
void test( node * &head, int data )
{
head = new node { data, head };
}
Without passing the head node by reference in the C function implementation the function deals with a copy of the value stored in head. You can imagine the function and its call the following way
test( head, 5 );
//...
void test( /*node *parm_head, int data*/ )
{
node *parm_head = head;
int data = 5;
node *new_node = ( node* )malloc( sizeof( node ) );
new_node->data = data;
new_node->next = *head;
*head= new_node;
}
That is function parameters are its local variables.
Consider another example when you need ay first to allocate an array to pointers to strings. For example
char **strings = malloc( 10 * sizeof( char * ) );
for ( size_t i = 0; i < 10; i++ )
{
strings[i] = malloc( 100 );
}
Now if you want to reallocate the original array by adding one more string then you gave to pass a pointer to this double pointer. For example
void add_one_more_string( char ***strings )
{
char **tmp = realloc( *strings, 11 ( sizeof( char * ) );
if ( tmp != NULL ) *stringvs = tmp;
//…
}
and call the function like
add_one_more_string( &strings );

what happens when a pointer is passed as a pointer to a pointer inside another function?

So can someone explain what would happen if I pass ...*p as the argument name for the foo function
int main()
{
int i = 10;
int *const p = &i;
foo(&p);
printf("%d\n", *p);
}
void foo(int **p)
{
int j = 11;
*p = &j;
printf("%d\n", **p);
}
Don't do that. You'll have a pointer to an undefined memory location on the stack. Any other function call between foo(&p); and printf("%d\n", *p); is bound to overwrite that memory location with new data.
Let's look at a simple example here! We have a function print_address, which takes an address and prints it. We're gonna print the address of an int, as well as the address of a pointer to that int, and a pointer of a pointer to that int.
#include <stdio.h>
void print_address(void* addr) {
printf("Address: %p\n", addr);
}
int main()
{
int value = 0;
int* value_ptr = &value;
int** value_ptr_ptr = &value_ptr;
print_address(&value);
print_address(&value_ptr);
print_address(&value_ptr_ptr);
return 0;
}
When I run this code, I get the following output:
Address: 0x7fffa4936fec
Address: 0x7fffa4936ff0
Address: 0x7fffa4936ff8
The first address is to value, the second address is to value_ptr, and the third address is to value_ptr_ptr. Each address is a little higher than the previous one, because each variable has been stored a little higher up on the stack.
The same thing happens with function calls. When we call a function, the memory for all the local variables in that function is stored a little higher up on the stack then the memory for all the local variables in the current function:
#include <stdio.h>
void print_address(void* addr) {
printf("Address: %p\n", addr);
}
void f3(int*** ptr) {
print_address(ptr);
}
void f2(int** ptr) {
print_address(ptr);
f3(&ptr);
}
void f1(int* ptr) {
print_address(ptr);
f2(&ptr);
}
int main()
{
int value = 0;
f1(&value);
return 0;
}
This time when I ran it, the output was
Address: 0x7ffeca71dc2c
Address: 0x7ffeca71dc08
Address: 0x7ffeca71dbe8
If you notice, the gaps between addresses are higher, but that's because of the extra stack space it takes to do a function call.
j is destoyed after exiting foo, so doing anything with it after foo calling in main is incorrect, until you reset it on another object (I mean printf("%d\n", *p)).
Well, what you're doing is passing pointer on pointer on integer.
As you could see, pointers are often used to pass arrays:
void print_array(int* a, int n) {
for (int i = 0; i < n; i++)
printf("%d ", a[i]);
printf("\n");
}
And pointers on pointers are used to pass two-dimensional arrays, for example in int main(int argc, char** argv) { ... } argv is array of strings or array of arrays of char-s.
You can't pass *p, but let's say you could...
It looks like you are trying to get your function to update a parent variable - and passing &p is the correct way to do it. But you are adding one too many dereference. I highly recommend you read this: https://boredzo.org/pointers/
// Let's assume you only have 4 memory locations for variables: 1 2 3 and 4.
// let's call these m[1] m[2] m[3] and m[4]
// i is at 1, p is at 2, j is at 3, and the p inside the function is at 4.
// let's call that second p, q rather
// so you have: m[1..4] = { i, p, j, q }
// now execute the code in your head:
int main()
{
int i = 10; // m[1] = 10
int *const p = &i; // m[2] = 1
foo(&p); // foo(2)
printf("%d\n", *p); // printf m[2]
}
void foo(int **q) // q = m[m[2]] = m[1] = 10
{
int j = 11; // m[3] = 11
*q = &j; // m[10] = 3 // segfault!
printf("%d\n", **q); // printf m[m[10]] = m[3] = 11 // if it didnt' segfault
}
It looks like this is what you are trying to do:
#include <stdio.h>
void b(int *q,int n) {
*q=n;
}
int main() {
int i=123;
int *p=&i; // *p and i are now synonymous
printf("%i ",i);
printf("%i ",*p); // same thing
b(p,111);
printf("%i ",i);
b(&i,111);a // same thing
printf("%i ",i);
}

casting pcap_if_t* to pcap_if_t** in c++

I have working of pcap library to sniff network traffic in c++.
In pcap library the pcap_if_t is a struct as below :
struct pcap_if {
struct pcap_if *next;
char *name; /* name to hand to "pcap_open_live()" */
char *description; /* textual description of interface, or NULL */
struct pcap_addr *addresses;
bpf_u_int32 flags; /* PCAP_IF_ interface flags */
};
typedef struct pcap_if pcap_if_t;
now, i am confused about using of &alldevs value in int pcap_findalldevs(pcap_if_t **, char *); prototype as the first value in bellow code. while, pcap_if_t *alldevs is a pointer and is not match with pcap_if_t ** parameter (which is a pointer that refers to another pointers).
pcap_if_t *alldevs;
char errbuf[PCAP_ERRBUF_SIZE];
/* Retrieve the device list from the local machine */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf);
exit(1);
}
For example even, i test "pointer to pointer" (a chain of pointers) with int **arr statement. i defined int **arr as a matrix :
int **arr = new int*[5];
for(int i = 0; i < 5; i++)
{
arr[i] = new int[3];
}
Then defined void print_arr(int **arr, int r, int c) function, due to print matrix values and gave it two different parameters (arr and &arr2):
int *arr2 = static_cast<int*>(*arr);
print_arr(arr, 5, 3); // arr defined in top
print_arr(&arr2, 5, 4); // arr2 is a pointer as *arr2
Regardless of offered example, c++ how behave with this conversion? its a few ambiguous to realize.
The & operator in this context is the address of operator. When you take the address of a variable, you get a pointer to that variable. A pointer stores an address.
e.g.:
int a = 1;
int *b = &a;
b now points to your a variable. Since a has the type int, &a gives you a type of pointer to int, an int*
The same thing happens if you do it one more time:
int a = 1;
int *b = &a;
int **c = &b;
Now c points to b. Since b has the type int *, &b gives you the type pointer to an int pointer, an int **
The same thing happens in your function call
if (pcap_findalldevs(&alldevs, errbuf) == -1)
You take the address of the alldevs variable. Since alldevs has the type pcap_if_t* , &alldevs has the type pcap_if_t**.
You could do it like this too:
pcap_if_t *alldevs;
pcap_if_t **alldevs_ptr = &alldevs;
if (pcap_findalldevs(alldevs_ptr, errbuf) == -1)
I wanna offer a good example with this code :
int f = 48;
int *g = &f;
int **h = &g;
int ***i = &h;
int ****j = &i;
cout << j << endl;
cout << &i << endl;
Here, j is a chain pointer that contains i address, so output will be as bellow :
0x7ffe373a6220
0x7ffe373a6220
Two results shown either j value (which address pointed to) and i memory address, which two are the same because j contains &i. and also h and &g as :
cout << h << endl;
cout << &g << endl;
Also, output shown h value (that pointed to g address) and &g, which here are the same :
0x7ffe373a6210
0x7ffe373a6210

Strange optimization of initialization

I realize that my example not correct in general. But interesting to find out how it works.
/* C/C++ (gcc-4.3.4) */
#include <stdio.h>
int main() {
/*volatile*/ int i = 5;
int j = 500;
int *p = &j;
printf( "%d %x\n", *p, p );
p++;
printf( "%d %x\n", *p, p ); // works correct with volatile (*p is 5)
//printf( "%d %x\n", *p, &i ); // works correct without volatile
return 0;
}
Is it some kind of optimization?
UPDT
Ok i got about UB. I won't hope on another else.
BUT if i have 2 int vars which placed adjacent to each others (see addresses) why this code shouldn't works?
p++;
The code has undefined behavior. Pointer is pointing to some garbage location. Dereferencing it leads to unpredicted results.
What do you call corerct?
It isn't guaranted, how variables will be stored, so ANY result is correct
Both variables are not necessarly adjacent in memory. You could use an array to do this.
#define PRINT(p) (printf("%i %p\n", *(p), (void *)(p)))
int t[2];
int *a = &t[0];
int *b = &t[1];
*a = 5;
*b = 6;
int *p = a;
PRINT(p);
++p;
PRINT(p);

C/C++ changing the value of a const

I had an article, but I lost it. It showed and described a couple of C/C++ tricks that people should be careful. One of them interested me but now that I am trying to replicate it I'm not being able to put it to compile.
The concept was that it is possible to change by accident the value of a const in C/C++
It was something like this:
const int a = 3; // I promise I won't change a
const int *ptr_to_a = &a; // I still promise I won't change a
int *ptr;
ptr = ptr_to_a;
(*ptr) = 5; // I'm a liar; a is now 5
I wanted to show this to a friend but now I'm missing a step. Does anyone know what's missing for it to start compiling and working?
ATM I'm getting invalid conversion from 'const int*' to 'int*' but when I read the article I tried and it worked great.
you need to cast away the constness:
linux ~ $ cat constTest.c
#include <stdio.h>
void modA( int *x )
{
*x = 7;
}
int main( void )
{
const int a = 3; // I promisse i won't change a
int *ptr;
ptr = (int*)( &a );
printf( "A=%d\n", a );
*ptr = 5; // I'm a liar, a is now 5
printf( "A=%d\n", a );
*((int*)(&a)) = 6;
printf( "A=%d\n", a );
modA( (int*)( &a ));
printf( "A=%d\n", a );
return 0;
}
linux ~ $ gcc constTest.c -o constTest
linux ~ $ ./constTest
A=3
A=5
A=6
A=7
linux ~ $ g++ constTest.c -o constTest
linux ~ $ ./constTest
A=3
A=3
A=3
A=3
also the common answer doesn't work in g++ 4.1.2
linux ~ $ cat constTest2.cpp
#include <iostream>
using namespace std;
int main( void )
{
const int a = 3; // I promisse i won't change a
int *ptr;
ptr = const_cast<int*>( &a );
cout << "A=" << a << endl;
*ptr = 5; // I'm a liar, a is now 5
cout << "A=" << a << endl;
return 0;
}
linux ~ $ g++ constTest2.cpp -o constTest2
linux ~ $ ./constTest2
A=3
A=3
linux ~ $
btw.. this is never recommended... I found that g++ doesn't allow this to happen.. so that may be the issue you are experiencing.
Note any attempt to cast away constness is undefined by the standard. From 7.1.5.1 of the standard:
Except that any class member declared
mutable can be modified, any
attempt to modify a const object
during its lifetime
results in undefined behavior.
And right after this example is used:
const int* ciq = new const int (3); // initialized as required
int* iq = const_cast<int*>(ciq); // cast required
*iq = 4; // undefined: modifies a const object
So in short what you want to do isn't possible using standard C++.
Further when the compiler encounters a declaration like
const int a = 3; // I promisse i won't change a
it is free to replace any occurance of 'a' with 3 (effectively doing the same thing as #define a 3)
Just a guess, but a common question is why one can't convert an int** to a const int**, which at first appears to be reasonable (after all, you're just adding a const, which is normally ok). The reason is that if you could do this, you could accidentally modify a const object:
const int x = 3;
int *px;
const int **ppx = &px; // ERROR: conversion from 'int**' to 'const int**'
*ppx = &x; // ok, assigning 'const int*' to 'const int*'
*px = 4; // oops, just modified a const object
It's a very non-intuitive result, but the only way to make sure that you can't modify a const object in this case (note how there are no typecasts) is to make line 3 an error.
You're only allowed to add const without a cast at the FIRST level of indirection:
int * const *ppx = &px; // this is ok
*ppx = &x; // but now this is an error because *ppx is 'const'
In C++, it is impossible to modify a const object without using a typecast of some sort. You'll have to use either a C-style cast or a C++-style const_cast to remove the const-ness. Any other attempt to do so will result in a compiler error somewhere.
Back in the mists of time, we paleo-programmers used FORTRAN. FORTRAN passed all its parameters by reference, and didn't do any typechecking. This meant it was quite easy to accidentally change the value of even a literal constant. You could pass "3" to a SUBROUTINE, and it would come back changed, and so every time from then on where your code had a "3", it would actually act like a different value. Let me tell you, those were hard bugs to find and fix.
Did you try this?
ptr = const_cast<int *>(ptr_to_a);
That should help it compile but it's not really by accident due to the cast.
In C++, Using Microsoft Visual Studio-2008
const int a = 3; /* I promisse i won't change a */
int * ptr1 = const_cast<int*> (&a);
*ptr1 = 5; /* I'm a liar, a is now 5 . It's not okay. */
cout << "a = " << a << "\n"; /* prints 3 */
int arr1[a]; /* arr1 is an array of 3 ints */
int temp = 2;
/* or, const volatile int temp = 2; */
const int b = temp + 1; /* I promisse i won't change b */
int * ptr2 = const_cast<int*> (&b);
*ptr2 = 5; /* I'm a liar, b is now 5 . It's okay. */
cout << "b = " << b << "\n"; /* prints 5 */
//int arr2[b]; /* Compilation error */
In C, a const variable can be modified through its pointer; however it is undefined behavior. A const variable can be never used as length in an array declaration.
In C++, if a const variable is initialized with a pure constant expression, then its value cannot be modified through its pointer even after try to modify, otherwise a const variable can be modified through its pointer.
A pure integral const variable can be used as length in an array declaration, if its value is greater than 0.
A pure constant expression consists of the following operands.
A numeric literal (constant ) e.g. 2, 10.53
A symbolic constant defined by #define directive
An Enumeration constant
A pure const variable i.e. a const variable which is itself initialized with a pure constant expression.
Non-const variables or volatile variables are not allowed.
Some of these answers point out that the compiler can optimize away the variable 'a' since it is declared const. If you really want to be able to change the value of a then you need to mark it as volatile
const volatile int a = 3; // I promise i won't change a
int *ptr = (int *)&a;
(*ptr) = 5; // I'm a liar, a is now 5
Of course, declaring something as const volatile should really illustrate just how silly this is.
this will create a runtime fault. Because the int is static. Unhandled exception. Access violation writing location 0x00035834.
void main(void)
{
static const int x = 5;
int *p = (int *)x;
*p = 99; //here it will trigger the fault at run time
}
You probably want to use const_cast:
int *ptr = const_cast<int*>(ptr_to_a);
I'm not 100% certain this will work though, I'm a bit rusty at C/C++ :-)
Some readup for const_cast: http://msdn.microsoft.com/en-us/library/bz6at95h(VS.80).aspx
const int foo = 42;
const int *pfoo = &foo;
const void *t = pfoo;
void *s = &t; // pointer to pointer to int
int **z = (int **)s; // pointer to int
**z = 0;
The article you were looking at might have been talking about the difference between
const int *pciCantChangeTarget;
const int ci = 37;
pciCantChangeTarget = &ci; // works fine
*pciCantChangeTarget = 3; // compile error
and
int nFirst = 1;
int const *cpiCantChangePointerValue = &nFirst;
int nSecond = 968;
*pciCantChangePointerValue = 402; // works
cpiCantChangePointerValue = &ci; // compile error
Or so I recall-- I don't have anything but Java tools here, so can't test :)
#include<iostream>
int main( void )
{
int i = 3;
const int *pi = &i;
int *pj = (int*)&i;
*pj = 4;
getchar();
return 0;
}
I was looking on how to convert between consts and I found this one http://www.possibility.com/Cpp/const.html maybe it can be useful to someone. :)
I have tested the code below and it successfully changes the constant member variables.
#include <iostream>
class A
{
private:
int * pc1; // These must stay on the top of the constant member variables.
int * pc2; // Because, they must be initialized first
int * pc3; // in the constructor initialization list.
public:
A() : c1(0), c2(0), c3(0), v1(0), v2(0), v3(0) {}
A(const A & other)
: pc1 (const_cast<int*>(&other.c1)),
pc2 (const_cast<int*>(&other.c2)),
pc3 (const_cast<int*>(&other.c3)),
c1 (*pc1),
c2 (*pc2),
c3 (*pc3),
v1 (other.v1),
v2 (other.v2),
v3 (other.v3)
{
}
A(int c11, int c22, int c33, int v11, int v22, int v33) : c1(c11), c2(c22), c3(c33), v1(v11), v2(v22), v3(v33)
{
}
const A & operator=(const A & Rhs)
{
pc1 = const_cast<int*>(&c1);
pc2 = const_cast<int*>(&c2),
pc3 = const_cast<int*>(&c3),
*pc1 = *const_cast<int*>(&Rhs.c1);
*pc2 = *const_cast<int*>(&Rhs.c2);
*pc3 = *const_cast<int*>(&Rhs.c3);
v1 = Rhs.v1;
v2 = Rhs.v2;
v3 = Rhs.v3;
return *this;
}
const int c1;
const int c2;
const int c3;
int v1;
int v2;
int v3;
};
std::wostream & operator<<(std::wostream & os, const A & a)
{
os << a.c1 << '\t' << a.c2 << '\t' << a.c3 << '\t' << a.v1 << '\t' << a.v2 << '\t' << a.v3 << std::endl;
return os;
}
int wmain(int argc, wchar_t *argv[], wchar_t *envp[])
{
A ObjA(10, 20, 30, 11, 22, 33);
A ObjB(40, 50, 60, 44, 55, 66);
A ObjC(70, 80, 90, 77, 88, 99);
A ObjD(ObjA);
ObjB = ObjC;
std::wcout << ObjA << ObjB << ObjC << ObjD;
system("pause");
return 0;
}
The console output is:
10 20 30 11 22 33
70 80 90 77 88 99
70 80 90 77 88 99
10 20 30 11 22 33
Press any key to continue . . .
Here, the handicap is, you have to define as many pointers as number of constant member variables you have.
we can change the const variable value by the following code :
const int x=5;
printf("\nValue of x=%d",x);
*(int *)&x=7;
printf("\nNew value of x=%d",x);
#include<stdio.h>
#include<stdlib.h>
int main(void) {
const int a = 1; //a is constant
fprintf(stdout,"%d\n",a);//prints 1
int* a_ptr = &a;
*a_ptr = 4;//memory leak in c(value of a changed)
fprintf(stdout,"%d",a);//prints 4
return 0;
}
Final Solution: it will change const variable a value;
cont int a = 10;
*(int*)&a= 5; // now a prints 5
// works fine.
The step you're missing is that you don't need the int* pointer. The line:
const int *ptr_to_a = &a; // I still promiss i won't change a;
actually says you won't change ptr_to_a, not a. So if you changed your code to read like this:
const int a = 3; // I promise I won't change a
const int *ptr_to_a = &a; // I promise I won't change ptr_to_a, not a.
(*ptr_to_a) = 5; // a is now 5
a is now 5. You can change a through ptr_to_a without any warning.
EDIT:
The above is incorrect. It turns out I was confusing a similar trick with a shared_ptr, in which you can get access to the raw pointer and modify the internal data value without firing off any warnings. That is:
#include <iostream>
#include <boost/shared_ptr.hpp>
int main()
{
const boost::shared_ptr<int>* a = new boost::shared_ptr<int>(new int(3));
*(a->get()) = 5;
std::cout << "A is: " << *(a->get()) << std::endl;
return 0;
}
Will produce 5.