Jump in the discussion.

No email address required.

Reported by:

It's hilarious how bug-ridden your short C code snippet is.

1. buffer contents aren't null-terminated properly, so printf will always do an out of bounds read. This is exactly the kind of bug that Rust is meant to prevent. BTW, even if it was terminated properly, it's generally a mistake to assume that an input file doesn't contain null bytes, you should instead use a function that takes the input size.

2. fseek and ftell are broken by design and they will not work with files larger than 2GB on the platforms where sizeof(long) == 4, e.g. Windows (both 32-bit and 64-bit) and 32-bit Linux.

3. The code doesn't check for ftell and fseek errors and potentially treats the error sentinel value (long)-1 as a filesize and passes it to calloc and fread.

Jump in the discussion.

No email address required.

Sure, here's a better version that addresses all 3*: https://stackoverflow.com/a/54057690 (this just limits file size, if you for some reason need to load large files in memory at once: https://wiki.sei.cmu.edu/confluence/display/c/FIO19-C.+Do+not+use+fseek%28%29+and+ftell%28%29+to+compute+the+size+of+a+regular+file (since you probably don't need this, just do it in chunks: https://stackoverflow.com/a/11792512))

*Well, looks like it still doesn't error check ftell. Imagine they do.

Remains perfectly readable unlike Crust.

Jump in the discussion.

No email address required.

What if you put a comment above each line?

pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
  // define a local helper function because GPT told me to
  fn inner(path: &Path) -> io::Result<Vec<u8>> {
    // open file for reading
    let mut file = File::open(path)?;

    // create a dynamically sized buffer to hold file contents
    let mut bytes = Vec::new();

    // read data into the buffer
    file.read_to_end(&mut bytes)?;

    // give buffer to the caller
    Ok(bytes)
  }

  // satisfy type system (I didn't go to college)
  inner(path.as_ref())
}
Jump in the discussion.

No email address required.

The syntax being confusing is to me specifically about, in order:

  • P: AsRef (P seems like a generic type like Java? But who knows what AsRef is doing here, is that just a pointer? Why isn't P reused, could it be? I'm guessing that P is now a generic type for a pointer to a Path?)

  • -> io::Result (is io a library, like C++? Why do I need to wrap my return vector in an io::Result? Is this like JS Promises? Nothing is manually returned, what is the return vector, bytes?)

  • path: &Path (is this dereferencing path?)

  • let mut file (is mut just saying file is non-const and can be redefined? Is that not the default like in every other language? Why is it needed here since file is never redefined? That leads me to suspect it actually means something else, if so wtf?)

  • File::open(path)? (wtf is the ? doing here? Is :: both how you refer to library types like io::Result and how you call static methods like File::open?)

  • Vec::new() (wait I thought this was a strongly typed language? Why is just a generic Vec allowed? Is there some default "bytes" type?)

  • (&mut bytes)? (so was bytes actually a pointer, and this is dereferencing it? I was assuming mut meant non-const when declaring variables, wtf is it doing here, also again wtf is the ? doing here)

  • Ok(bytes) (I guess Ok probably returns whatever you give it? Tbf your comment here does imply an answer to this one)

  • inner(path.as_ref()) (I'm left suspicious that "ref/AsRef" isn't just a pointer, because doesn't Rust just have normal * syntax for pointers too? Also wait, read takes in a ref to a path, right? But then it calls inner with path.as_ref. Wtf, isn't it now a pointer to a pointer, then dereferenced in inner automatically with path: &Path, resulting in path being a pointer in inner? If so is this intentional??? Maybe File::open expects a pointer to a Path and not a Path?)

Could I answer all these questions with some learning and research? Yeah ofc. But I refuse, trannies should try again and make their language less obtuse.

Jump in the discussion.

No email address required.

Your entire argument is basically "ChatGPT generated some shit that I don't understand and I'm too lazy to read a tutorial/book." It's fascinating that with your level of knowledge, you think you're entitled to having an opinion.

"I should be able to understand this without learning!!!" Yeah, just like you wrote broken C code that you thought you understand. You don't even seem to have a good grasp of C and C++, and yet expect to magically know Rust. The questions about basic syntax and error handling could be easily answered by skimming through a few chapters of "Programming Rust".

Also, the code is complicated because the inner wrapper is entirely pointless.

This code is fully equivalent to the original version:

pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
    let mut file = File::open(path)?;
    let mut bytes = Vec::new();
    file.read_to_end(&mut bytes)?;
    Ok(bytes)
}

Second of all, you "wrote" a generic function that takes arguments of multiple types (path objects/strings). If we simplify it to taking just strings, it would look like this:

pub fn read(path: &str) -> io::Result<Vec<u8>> {
    let mut file = File::open(path)?;
    let mut bytes = Vec::new();
    file.read_to_end(&mut bytes)?;
    Ok(bytes)
}
Jump in the discussion.

No email address required.

>Also, the code is complicated because the inner wrapper is entirely pointless.

wrong

Jump in the discussion.

No email address required.

Elaborate

Jump in the discussion.

No email address required.

Jump in the discussion.

No email address required.

:#marseyboar:

Jump in the discussion.

No email address required.

Ah, so you deliberately chose to use a highly optimized version of Rust code to compare with random basic bitch C++ code . The equivalent Rust would be the one given above as:

pub fn read(path: &str) -> io::Result<Vec<u8>> {
    let mut file = File::open(path)?;
    let mut bytes = Vec::new();
    file.read_to_end(&mut bytes)?;
    Ok(bytes)
}

(and to answer one of your questions yes Rust is strongly typed. You are able to instantiate Vec::new(); like that without type because unlike primitive C++, the rustc compiler is able to infer the type of elements contained in the Vector at compile time because of the 'file.read_to_end(&mut bytes)' line and is able to insert that itself. If you got rid of that line the code would fail to compile because of the missing type annotation)

The correct fair comparison to what you wrote would be some optimized monstrosity from the C++ standard library. Then we can really see what's simpler.

Jump in the discussion.

No email address required.

Just read the book and my r-slurred choices will make sense!!!

:wingcucks#:

:gigachad2: : :dukenuk#emtldr:

Jump in the discussion.

No email address required.

language bad because I'm too r-slurred to google beginner questions

Jump in the discussion.

No email address required.

Beginners to a language shouldn't need to go down a dozen weird syntax rabbit holes to completely understand every part of something as basic as reading a file. KISS

Jump in the discussion.

No email address required.

ahhhh namespaces ahhhhhh algebraic types my head nooooooooooooo

Jump in the discussion.

No email address required.

Those are like the two least weird because they're similar to C++ and Java sure.

Some of the pointer stuff I can at least guess at.

Haven't the foggiest what the ? could mean as used here. You can at least admit that's weird

Jump in the discussion.

No email address required.

:#marseyserioushatfact:

You should be able to write code day 1 that looks like it works (but will actually corrupt your data)

Jump in the discussion.

No email address required.

:marseyagreefast:

A programming language is like a gun, it should be usable by as many people as possible :marseysaluteusa:

Jump in the discussion.

No email address required.

This is one of the worst posts I have EVER seen. Delete it.

Jump in the discussion.

No email address required.

>"understands" C pointers

>frightened and confused at pass-by-reference

Jump in the discussion.

No email address required.

Yeah that one's on me, pretty much same as C/C++, been a while since I've touched either :marseyderp:

Jump in the discussion.

No email address required.

With colons, the type comes after the variable name. With that, most of your syntax confusion goes away.

P: AsRef

P is of type "AsRef"

path: &Path

path is of type "&Path", which is a reference to an object of type Path

mut is deeper than just const or non-const. By default, the variable and all its internal components are const. mut gives you the ability to call functions that reassign some internal variable that's part of the outer thing you're calling on.

? is a shortcut for "unwrap or return an error" for the Result monad in rust

Jump in the discussion.

No email address required.

By default, the variable and all its internal components are const

:pepereeeeee: I HATE IT

Good explanations tho ty :marseythumbsup:

Jump in the discussion.

No email address required.

!codecels He should've used D

Jump in the discussion.

No email address required.

ONLY use languages approved by Walter Bright!

Jump in the discussion.

No email address required.

It's hilarious how bug-ridden your short C code snippet is.

I don't think it's hilarious

Jump in the discussion.

No email address required.

kek C-huds rekt

Jump in the discussion.

No email address required.

Factcheck: This claim is 100% true.

Jump in the discussion.

No email address required.

C tards are relics of a dying world. All a la mode programmers know this.

Jump in the discussion.

No email address required.



Link copied to clipboard
Action successful!
Error, please refresh the page and try again.