@@ -150,26 +150,36 @@ If you really want global mutable state, try using `static mut` or a global
150
150
"## ,
151
151
152
152
E0018 : r##"
153
- The value of static and const variables must be known at compile time. You
154
- can't cast a pointer as an integer because we can't know what value the
155
- address will take.
156
153
157
- However, pointers to other constants' addresses are allowed in constants,
158
- example:
154
+ The value of static and constant integers must be known at compile time. You
155
+ can't cast a pointer to an integer because the address of a pointer can
156
+ vary.
159
157
158
+ For example, if you write:
160
159
```
161
- const X: u32 = 50;
162
- const Y: *const u32 = &X;
160
+ static MY_STATIC: u32 = 42;
161
+ static MY_STATIC_ADDR: usize = &MY_STATIC as *const _ as usize;
162
+ static WHAT: usize = (MY_STATIC_ADDR^17) + MY_STATIC_ADDR;
163
163
```
164
164
165
- Therefore, casting one of these non-constant pointers to an integer results
166
- in a non-constant integer which lead to this error. Example:
165
+ Then `MY_STATIC_ADDR` would contain the address of `MY_STATIC`. However,
166
+ the address can change when the program is linked, as well as change
167
+ between different executions due to ASLR, and many linkers would
168
+ not be able to calculate the value of `WHAT`.
169
+
170
+ On the other hand, static and constant pointers can point either to
171
+ a known numeric address or to the address of a symbol.
167
172
168
173
```
169
- const X: u32 = 1;
170
- const Y: usize = &X as *const u32 as usize;
171
- println!("{}", Y);
174
+ static MY_STATIC_ADDR: &'static u32 = &MY_STATIC;
175
+ // ... and also
176
+ static MY_STATIC_ADDR2: *const u32 = &MY_STATIC;
177
+
178
+ const CONST_ADDR: *const u8 = 0x5f3759df as *const u8;
172
179
```
180
+
181
+ This does not pose a problem by itself because they can't be
182
+ accessed directly.
173
183
"## ,
174
184
175
185
E0019 : r##"
@@ -347,55 +357,59 @@ From [RFC 246]:
347
357
[RFC 246]: https://github.com/rust-lang/rfcs/pull/246
348
358
"## ,
349
359
360
+
350
361
E0395 : r##"
351
- The value assigned to a constant expression must be known at compile time,
352
- which is not the case when comparing raw pointers. Erroneous code example:
362
+ The value assigned to a constant scalar must be known at compile time,
363
+ which is not the case when comparing raw pointers.
353
364
365
+
366
+ Erroneous code example:
354
367
```
355
- static foo : i32 = 42;
356
- static bar : i32 = 43 ;
368
+ static FOO : i32 = 42;
369
+ static BAR : i32 = 42 ;
357
370
358
- static baz : bool = { (&foo as *const i32) == (&bar as *const i32) };
371
+ static BAZ : bool = { (&FOO as *const i32) == (&BAR as *const i32) };
359
372
// error: raw pointers cannot be compared in statics!
360
373
```
361
374
362
- Please check that the result of the comparison can be determined at compile time
363
- or isn't assigned to a constant expression. Example:
375
+ The address assigned by the linker to `FOO` and `BAR` may or may not
376
+ be identical, so the value of `BAZ` can't be determined.
377
+
378
+ If you want to do the comparison, please do it at run-time.
379
+
380
+ For example:
364
381
365
382
```
366
- static foo : i32 = 42;
367
- static bar : i32 = 43 ;
383
+ static FOO : i32 = 42;
384
+ static BAR : i32 = 42 ;
368
385
369
- let baz: bool = { (&foo as *const i32) == (&bar as *const i32) };
386
+ let baz: bool = { (&FOO as *const i32) == (&BAR as *const i32) };
370
387
// baz isn't a constant expression so it's ok
371
388
```
372
389
"## ,
373
390
374
391
E0396 : r##"
375
- The value assigned to a constant expression must be known at compile time,
376
- which is not the case when dereferencing raw pointers. Erroneous code
377
- example:
392
+ The value behind a raw pointer can't be determined at compile- time
393
+ (or even link-time), which means it can't be used in a constant
394
+ expression.
378
395
396
+ For example:
379
397
```
380
- const foo: i32 = 42;
381
- const baz: *const i32 = (&foo as *const i32);
398
+ const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
382
399
383
- const deref: i32 = *baz ;
400
+ const VALUE: u8 = unsafe { *REG_ADDR } ;
384
401
// error: raw pointers cannot be dereferenced in constants
385
402
```
386
403
387
- To fix this error, please do not assign this value to a constant expression.
388
- Example:
404
+ A possible fix is to dereference your pointer at some point in run-time.
389
405
390
- ```
391
- const foo: i32 = 42;
392
- const baz: *const i32 = (&foo as *const i32);
406
+ For example:
393
407
394
- unsafe { let deref: i32 = *baz; }
395
- // baz isn't a constant expression so it's ok
396
408
```
409
+ const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
397
410
398
- You'll also note that this assignment must be done in an unsafe block!
411
+ let reg_value = unsafe { *REG_ADDR };
412
+ ```
399
413
"## ,
400
414
401
415
E0397 : r##"
0 commit comments