<p>There are situations during compilation when some identifier represents a particular value (&quot;contained&quot; in a variable, etc), but sometimes it references the variable's memory location directly.</p>
<p>How does the compiler know which is intended, to generate the correct code?</p>

<compilers><implementation>
How does a compiler know that an identifier in an expression refers to a memory location, or the value stored at that location?
CC BY-SA 4.0
2023-05-31T21:11:07.017Z
It sounds like you're asking about *rvalues* vs *lvalues*, to use the C++ terminology. Is that correct?
Bbrk24
CC BY-SA 4.0
2023-06-01T04:35:49.960Z
In essence yes. But there are situations where you would still treat an lvalue like an rvalue, depending on context, but I have been struggling to implement this all correctly in my  own compiler project
springogeek
<p>The easy way of answering this is to just define, in each grammatical context, whether the name of a reference means the reference itself or the referenced value. So if <code>x</code> is a reference, and a reference in a simple name expression means a reference, then <code>x + 7</code> gives a type error; inconvenient, but easy for the compiler. Then it's the user's responsibility to write <code>*x + 7</code> when they want the referenced value. However, even strongly-typed languages like Rust usually aren't this pedantic about references.</p>
<p>The more ergonomic way of doing it is by implicit coercions, using information about static types. Let's use a more familiar example from Java:</p>
<pre class="lang-java prettyprint-override"><code>int x = 5;
System.out.println(x + 2.5);
</code></pre>
<p>Here the variable <code>x</code> is an integer, but its value must be a <code>double</code> for the expression <code>x + 2.5</code> to make sense. The compiler knows (based on the static types of the expressions) that the expression <code>x</code> is expected to produce a <code>double</code> but it is actually of type <code>int</code>, and so it inserts a coercion from <code>int</code> to <code>double</code>.</p>
<p>Likewise, consider the following Rust code:</p>
<pre class="lang-rust prettyprint-override"><code>let x_val = 5;
let x_ref = &amp;x_val;
print!(&quot;{}&quot;, x_ref + 7);
</code></pre>
<p>In this code, <code>x_ref</code> has type <code>&amp;i32</code>, a reference to an integer. But in the expression <code>x_ref + 7</code>, an <code>i32</code> is expected. The Rust compiler knows both of these facts, because of the static type of <code>x_ref</code> and the static type expected by the <code>+</code> operator (given that its other operand is an integer), so it inserts a coercion from <code>&amp;i32</code> to <code>i32</code> by dereferencing.</p>

CC BY-SA 4.0
2023-05-31T21:18:47.497Z
2023-05-31T21:18:47.497Z
kaya3
# How does a compiler know that an identifier in an expression refers to a memory location, or the value stored at that location?
Posted by: username_0 on 2023-05-31
There are situations during compilation when some identifier represents a particular value ("contained" in a variable, etc), but sometimes it references the variable's memory location directly.

How does the compiler know which is intended, to generate the correct code?
**Tags:** compilers implementation
> **Comments:**
> **username_1**: It sounds like you're asking about *rvalues* vs *lvalues*, to use the C++ terminology. Is that correct?  
> **username_0**: In essence yes. But there are situations where you would still treat an lvalue like an rvalue, depending on context, but I have been struggling to implement this all correctly in my  own compiler project  
---
## 1 answers
### Answer by username_2 on 2023-05-31. Score: 5
The easy way of answering this is to just define, in each grammatical context, whether the name of a reference means the reference itself or the referenced value. So if x is a reference, and a reference in a simple name expression means a reference, then x + 7 gives a type error; inconvenient, but easy for the compiler. Then it's the user's responsibility to write *x + 7 when they want the referenced value. However, even strongly-typed languages like Rust usually aren't this pedantic about references.
The more ergonomic way of doing it is by implicit coercions, using information about static types. Let's use a more familiar example from Java:
int x = 5;
System.out.println(x + 2.5);

Here the variable x is an integer, but its value must be a double for the expression x + 2.5 to make sense. The compiler knows (based on the static types of the expressions) that the expression x is expected to produce a double but it is actually of type int, and so it inserts a coercion from int to double.
Likewise, consider the following Rust code:
let x_val = 5;
let x_ref = &x_val;
print!("{}", x_ref + 7);

In this code, x_ref has type &i32, a reference to an integer. But in the expression x_ref + 7, an i32 is expected. The Rust compiler knows both of these facts, because of the static type of x_ref and the static type expected by the + operator (given that its other operand is an integer), so it inserts a coercion from &i32 to i32 by dereferencing.
---
