The address of a literal

Pages: 12
Hi there!

I'd like to know why I can't take the address of a literal directly. For example in that way:

int* ptr = &10;

But this code is correct:

1
2
int& ref = 55;
int* ptr = &ref;


Why is that ?
Because also the second one is wrong
As i know..
in

int* ptr= &10;


ptr is pointer of int type.. it can take address of any int variable..
that is why first code is wrong.
in second code

ptr is pionter of int data type.. and holding address of ref that is why it is correct
(Sorry, I forgot const in the second code)

EDIT:

ADii wrote:
ptr is pointer of int type.. it can take address of any int variable..
that is why first code is wrong.


Check it out:

/*const - not necessary*/ char* ptr = "C-string...";

According to you, ptr "can take address of any char variable". And that's not true, because 'C' is the part of the literal...

Last edited on
const???


what statement you want to make constant?
ADii wrote:
what statement you want to make constant?


1
2
const int& ref = 55;
const int* ptr = &ref;


(I use Comeau C++ Online - http://comeaucomputing.com/tryitout/).
okay i think.. ..
ptr is holding rec address permanently and cannot be change
A literal integer value doesn't necessarily exist in the data space of your program. (Actually, it rarely does.)

Hence, you cannot take its address.


If you want something modifiable, use a variable:
1
2
3
int x = 42;
int* p = &x;
etc

Hope this helps.
/*const - not necessary*/ char* ptr = "C-string...";


Err.. the const is necessary. Right? A lot of compilers let you slide without the const, but that's deprecated behavior AFAIK.
For character literals, the const is typically required to be there. Whether or not that is the case depends on your compiler.

For example, older versions of the GCC let you get away with things like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* This example program expects that string constants to be stored
 * in WRITABLE memory.
 *
 * The GCC 4.x series no longer allows this -- so this program will
 * not compile for the latest GCC.
 *
 * On the GCC 3.x series, compile with the -fwritable-strings flag:
 *
 *   gcc -fwritable-strings -o stupid stupid.c
 *
 * For other compilers, your results may vary.
 */

#include <stdio.h>
#include <string.h>

int main() {
  printf( "%s\n", strcpy( "Stupider", "Stupid" ) );
  return 0;
  }

The reason is that string literals are typically placed in read-only program memory, so they must be declared as const char*.
Duoas wrote:
A literal integer value doesn't necessarily exist in the data space of your program. (Actually, it rarely does.)

Hence, you cannot take its address.


Yes, I know. But a reference is a kind of pointer, so it needs the address of r-value, too...
You can't take the address of a literal (so the address of a literal cannot be assigned to a pointer).

references are not pointers (in the c++ sense) and behave differently with regards to literals.
You can bind a reference to a literal because
a temporary variable is created from the literal and the and it is this temporary variable that is used by the the reference. Temporary variables are constant.
See this snippet from the c++ standards document:
...SNIP ....
Otherwise, a temporary of type “cv1 T1” is created and initialized from the initializer expression
using the rules for a non-reference copy initialization (8.5). The reference is then bound to the temporary.
If T1 is reference-related to T2, cv1 must be the same cv-qualification as, or greater cvqualification
than, cv2; otherwise, the program is ill-formed.

[Example:
const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0

....SNIP....
guestgulkan wrote:
You can bind a reference to a literal because a temporary variable is created from the literal


Then why it couldn't be created when we're taking its address directly ?

const int* ptr = &50;

TBH, I believe the bottom line answer is that taking the address of a literal was never allowed in C and this is carried over to C++.


personally, I think taking the address of a literal is pointless, and I can't think of any particular reason to
explicitly create a reference to a literal (although compilers do implicitly create them during function calls);
Yes, I know. But a reference is a kind of pointer, so it needs the address of r-value, too...


This seems to be what is getting you.

References are not pointers.

1
2
int var = 100;
int& ref = var;


ref does not "point to" var.
ref is var. They're one and the same.

This is different both conceptually, and in how the compiler generates the code.


As for being able to point to string literals, C/C++ make an exception to the rule for that, simply because there's really no other way to handle hardcoded strings in a program.

Strings do not exist in the actual assembly. IE you can't do something like mov eax, "a string literal". Other types of literals do exist in the assembly, though. mov eax, 5 for instance.

Therefore the compiler takes all the string literals in a program, slaps them somewhere else in the compiled binary, and let's you refer to them via pointer.

In theory, it could do the same with other types so that you could point to other literals, but there wouldn't really be any point to that.
In all existing implementations, a reference is a pointer.

The trick is not confusing the low-level construct from the high-level construct. When we are talking about taking the address of something, that is a low-level construct. When we are talking about references, we are talking about a high-level construct.

The purpose of high-level constructs is to think about things more like humans do, instead of the low-level, think more like the computer does, construct. References give you a lot of nice guarantees, and make it easier for the compiler to optimize them. Pointers explicitly countermand that possibility.


The problem with literals is that they don't necessarily exist. The compiler is not only free to, but may need to, put them in the code in such a way that they cannot be accessed directly.
guestgulkan wrote:
personally, I think taking the address of a literal is pointless, and I can't think of any particular reason to explicitly create a reference to a literal


I think so too...

Disch wrote:
In theory, it could do the same with other types so that you could point to other literals, but there wouldn't really be any point to that.


OK, I understand :)
Disch wrote:
References are not pointers.


Duoas wrote:
In all existing implementations, a reference is a pointer.


:)

Duoas wrote:
put them in the code in such a way that they cannot be accessed directly.


Processor constant registers for example ?
Yes. For example, a MIPS processor packs both the instruction code and the values in the same machine word. You cannot reference a bitpacked field transparently (not without some significant overhead).
In all existing implementations, a reference is a pointer.


Not necessarily true. The compiler is more likely to optimize away a reference than it is a pointer.

1
2
3
4
5
6
7
8
9
10
int foo = 0;
int& bar = foo;

++bar;  // compiler is likely to optimize away 'bar' and just do ++foo;

//=================

int* ptr = &foo;

++(*ptr);  // compiler is less likely to optimize away 'ptr' 
Pages: 12