1

I have a function like this in my static library crate:

use super::*;

static BLANK_VEC: [u8; 16] = [0_u8; 16];
pub fn pad(name: &'static str) -> String {
    let mut res = String::from(name);
    res.push_str(&String::from_utf8_lossy(&BLANK_VEC[name.len()..]));
    res
}

When I link this to C code it works as expected, but if I link with the below code (the only difference being const instead of static) the label BLANK_VEC doesn't appear in the ELF file. It could compile and run until it gets a HardFault.

use super::*;

const BLANK_VEC: [u8; 16] = [0_u8; 16];
pub fn pad(name: &'static str) -> String {
    let mut res = String::from(name);
    res.push_str(&String::from_utf8_lossy(&BLANK_VEC[name.len()..]));
    res
}

Is this a bug on the Rust side? I think so because the const variable goes out of scope somehow. I can reference it and it compiles. Where is the ensured memory safety? Why didn't I have to use unsafe block to do that?

If this is something that depends on my linker: I use arm-gcc-none-eabi.

Edit: I understand why this happens but shouldn't Rust ensure that the user uses a variable that won't disappear?

  • 2
    See also https://stackoverflow.com/a/52753798/1021920 especially the text below "**Occurrences**" – hellow Mar 10 '21 at 10:13
  • https://stackoverflow.com/questions/52751597/what-is-the-difference-between-a-constant-and-a-static-variable-and-which-should/52753798#52753798 and https://stackoverflow.com/questions/45550387/how-can-i-access-a-c-global-variable-constant-in-rust-ffi escpecially the part `const and static do not mean the same things in Rust and C` – KamilCuk Mar 11 '21 at 15:15
  • 1
    Since the question has already had a good answer posted, I think it would be better to leave this question as *why does the symbol `BLANK_VEC` not appear in the linker output* (which is what Masklinn answered) and open a new question for *why do I get an error when I run this code* (for which you should also provide more context, like the C code you're linking to). Changing the question after answers have already been posted is frowned on; opening a new question is fine and encouraged. – trent Mar 11 '21 at 20:54
  • ok will do that – paranoid_android Mar 11 '21 at 22:27

1 Answers1

4

It's not a bug in rust: const defines a constant value copied at every use-site (therefore not existing at runtime).

static defines a global variable (which may or may not be constant), and is thus present in the final program, it's an actual single location in memory.

Masklinn
  • 34,759
  • 3
  • 38
  • 57
  • Ok but why does it compile. Isn't this unsafe. There should be at least a warning in my opinion about this. You are right this isn't a bug but this doesn't look like something Rust would do. – paranoid_android Mar 10 '21 at 21:00
  • 1
    Linking is inherently unsafe; see [issue #28179](https://github.com/rust-lang/rust/issues/28179). However, I don't see any unsafety here. Why do you think this *particular* code is unsafe? – trent Mar 10 '21 at 21:53
  • @selmanözlyn why would it not compile? There's nothing unsafe about anything, a `const` value just just copied at every use site. The linker is not under Rust's purview, that your C and linking are broken are not its problems. – Masklinn Mar 11 '21 at 06:49
  • 2
    Incidentally assuming that *private* statics are labelled in the output seems optimistic. I'd assume rustc within its right to not embed it since it's not visible in the output. – Masklinn Mar 11 '21 at 06:51
  • Linking is inherently unsafe might be my answer maybe. @Masklinn It would compile, I am saying why doesn't it force me to use a variable that won't disappear. When does it disappear when I am linking? When I use staticlib? Maybe there could be a warning right? So can we say there is no memory safety ensurance when linking. – paranoid_android Mar 11 '21 at 15:08
  • @selmanözlyn Why do you think there is memory unsafety? Why would `BLANK_VEC` have to appear in the output for `pad` to be memory safe? – trent Mar 11 '21 at 15:15
  • Because I am using it... And it lets me use it then I get a HardFault. The problem isn't the HardFault it is Rust letting me use it. I can use something doesn't appear and something that isn't in my scope – paranoid_android Mar 11 '21 at 15:39
  • 1
    @selmanözlyn Anywhere Rust lets you use a name, it is by definition in scope. `BLANK_VEC` has no *linkage*, but that pertains to the use of the symbol `BLANK_VEC` and not the value behind it, which is always valid. It's like a `#define` in C, or an `inline constexpr` in C++, which also don't have linkage. I don't know what HardFault means, but if it's a runtime memory error, maybe that means you have an incorrect `unsafe` somewhere, or your C code is misbehaving. There's no reason Rust should warn you about using `BLANK_VEC` in this code; there's no way to use it to create unsafety. – trent Mar 11 '21 at 17:07
  • Its a runtime memory error. How can I change the question? Clearly I wasn't understood. – paranoid_android Mar 11 '21 at 19:49
  • 1
    @selmanözlyn you don't change questions days later, you create new questions, or go ask question on sites more adapted to discussing things (which SO *really* is not, because the commenting system is crap). – Masklinn Mar 12 '21 at 06:40
  • Ok thanks when I have the time I will open it. – paranoid_android Mar 12 '21 at 16:51