-
Pointers and constants
Hello everyone! I've just started to learn C++ and have a question... I've written the following code:
Code:
#include <iostream.h>
int main()
{
const int i=1;
int* pi;
//pi = &i; Error, since pi isn't declared as a pointer\
which points to a constant
pi = (int*) &i; // Address of constant i allocated \
to pointer pi with a cast
*pi = 2;
cout << "Address of i:\t\t" << &i << endl;
cout << "pi points to:\t\t" << pi << endl;
cout << "Value of i:\t\t" << i << endl;
cout << "Value pointed to by pi:\t" << *pi << endl;
return 0;
}
which produces in my computer the following output:
Address of i: 0x0012FF7C
pi points to: 0x0012FF7C
Value of i: 1
Value pointed to by pi: 2
Now, my question is, why, if the address of i and the address pointed to by pi are the same, can I (apparently) have two different values stored in this same address? I'm sure I'm missing something here, maybe I have some conceptual misconception on the subject pointers... Any help would be much appreciated.
-
Simple example of type-abuse.
If you go out of your way to cast away all the useful warnings, don't complain when it all goes wrong.
> cout << "Value of i:\t\t" << i << endl;
The compiler knows i is const (despite your efforts), and simply generates the code
cout << "Value of i:\t\t" << 1 << endl;
without ever referring to the storage location called i
-
Aha! That makes a lot of sense, I should've thought of it. But when you said compiler you meant preprocessor, right? (just an honest question from a newbie trying to figure out how this thing works...)
Thanks! :)
-
No, I meant compiler.
The pre-processor deals with #include, #if and #define
-
That means, if I define a constant with #define, it will be dealt with by the preprocessor, whereas if I define it with const, then it will be the compiler who deals with it? Do you have any advice on what's better?
-
const is very much preferred in C++, primarily because it is type-safe. The pre-processor is just an 'on the fly' editor of your code, doing some fairly crude search/replace text substitutions. Occasionally, this produces some real surprises for the programmer.
In C, you have to use the pre-processor for things like
Code:
#define SIZE 10
#define max(a,b) a>b?a:b /* this is a dangerous macro */
int arr[SIZE];
Because you can't do
Code:
const int SIZE = 10;
int arr[SIZE]; /* doesn't work in C */
In C++, you would do this
Code:
const int SIZE = 10;
inline int max( int a, int b ) {
return a>b?a:b;
}
int arr[SIZE];
Inline functions are as fast as the macro versions, but again they are type-safe.
For example, this would compile OK using the #define, but would produce some odd results at run-time.
It would not compile at all with the C++ inline function
Code:
char *p = max( "hello", "world" );
In addition, the inline function does not suffer from multiple evaluation problems, like
Code:
int c = max( a++, b++ );
In C (using the macro), this expands to
Code:
int c = a++ > b++ ? a++ : b++;
Which results in either a or b being incremented TWICE (almost certainly not what you wanted / expected).
-
I see... thank you very much for the detailed explanation!