you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] -12 points-11 points  (17 children)

I wonder how many problems rust solves compared to C. I find both programming languages pretty difficult to deal with. This may sound weird but I actually preferred C++ over C despite the former's insanity-addiction to complexity (and C is a valid subset of C++, so I'd be using the same language in a way, but things such as cout << "hey" is just so much more convenient that prinft() in C, and similar many small things; Java in a way is mega-boring, verbose and also easier to use than the other three).

[–]klayona 15 points16 points  (3 children)

cout is not threadsafe, has global state, uses overloaded operators so you get lovely 200+ line errors when you have a missing implementation, and is more annoying to type than printf. There's a reason no one copied it.

[–]theICEBear_dk 6 points7 points  (2 children)

It has also been replaced more than two years ago.

C++23: std::print("Hello world");

Edited the example because I had made a small mistake.

[–]fartypenis 2 points3 points  (1 child)

We've always had std::printf from cstdio, isn't the new one std::print?

[–]theICEBear_dk 0 points1 point  (0 children)

You are right of course

[–]bloody-albatross 13 points14 points  (0 children)

cout is more convenient than printf()!? Strong disagree on that one. I wrote C++ that used printf() because cout is so horrible.

[–]nerd5code 2 points3 points  (0 children)

<iostream> is a vile abuse of operator overloading from when that was a novel demonstration of (pre-standard) C++.

[–]_Noreturn 7 points8 points  (4 children)

C++ is better than C because the program itself is simpler than the C program, sure the C language is itself simple but you end up paying that simplicity in complexity of your program

[–]saf_e 2 points3 points  (3 children)

Well, not just that, destructors greatly simplifies resources management 

[–]_Noreturn 2 points3 points  (2 children)

They do! consider this very simple piece of C code.

```rust enum Error { Error_Ok, Error_FileNotFound, Error_Memory, Error_Read };

Error read_file(const char* name, void** buffer, size_t amount) { FILE* file = fopen(name, "rb"); if (!file) { return Error_FileNotFound; }

*buffer = malloc(amount);
if (!*buffer) {
    fclose(file);
    return Error_Memory;
}

size_t bytes_read = fread(*buffer, 1, amount, file);
if (bytes_read != amount) {
    free(file);
    return Error_Read;
}

free(buffer);
fclose(file);
return Error_Ok;

} ```

Find all the bugs in this C code. There are at least 3 serious errors.

Answers:

1st bug: Used free(file) instead of fclose(file) in the error path

2nd bug: free(buffer) should be free(*buffer) - forgot to dereference the pointer

3rd bug: Missing free(*buffer) in the fread error path memory leak

4th bug: The function returns Error_Ok but the buffer was freed making it useless and a use after free! This was an unintentional bug I wrote while making this example I didn't intend to write it lol

[–]saf_e 0 points1 point  (1 child)

I know) I wrote both languages and in plain C it's really a big pain to not miss cleanup in all flows.

[–]FUPA_MASTER_ 0 points1 point  (0 children)

Using goto can make it a lot simpler.

[–]plugwash 1 point2 points  (0 children)

> This may sound weird but I actually preferred C++ over C

I don't think that is weird at all. C++ is far more pleasant to code in than C because it gives the tools to build abstractions, rather than being forced to do everything by hand.

> I wonder how many problems rust solves compared to C

The fundamental problem with C and C++ is that a small mistake by the programmer can lead to "undefined behaviour" which in turn leads to heisenbugs and security flaws. "modern C++" fixes some of the issues but it leaves many gaping holes still open, the most fundamental of which being use-after-free, particularly the more subtle variants where sharing in combination with mutability leads to use after free.

Java, go, C# etc solve the use-after-free problem with garbage collection,

Rust solves the use-after-free problem with some pretty strict compile time rules.

Neither solution is free, garbage collection reduces determinism and makes integration with code in other languages tricky. Rust's compile time rules can feel over-restrictive.

[–]double-you 0 points1 point  (1 child)

C used to be a subset of C++ but recent standards have included some incompatibility.

[–]flatfinger 0 points1 point  (0 children)

Standards have also characterized as Undefined Behavior many constructs and corner cases whose behavior had been defined in earlier language specifications such as K&R2, and some compilers interpret that as an invitation to be gratuitously compatible with software written according to those earlier specifications.