Earlier quoted context omitted.
Well, yes if the strawman "all modern C++ written by experts is free from memory safety issues" is what you're countering. I find that to be gratuitous and petty, and not a good representation of Rust, however.
The position "modern C++ is safe and all C programmers are idiots" is repeated quite often here on HN. To be fair, it is always the same small group of people who do that.
Regex: badly needs fuzzing
151–160 of 180 posts
Re: Regex: badly needs fuzzing
#152Earlier quoted context omitted.
re2 is not only about exponential time: matching of regexes like a|b|c is O(N) in backtracking engines and O(1) in DFA-based engines like re2. It can make a big difference in practice for generated regexes - e.g. if you want to check if an URL has one of the thousand substrings in it (think adblock-like use cases). With backtracking regex or with a loop it'd be O(N) regarding the number of options, but with DFA it is…
How does the DFA engine match anything without looking at the whole input?
Re: Regex: badly needs fuzzing
#153Am i the only one, who get slowly angry about that "Use $language but Not this One"-comments? I don't see much value in such comments, srsly. Why don't accept the fact someone decided to write $it, and move on with usefull comments? Enough hn this today.
Re: Regex: badly needs fuzzing
#154Earlier quoted context omitted.
Yes, I had a similar thought. The top two comment chains right now are (to paraphrase) "See, modern C++ isn't free of memory issues" and "Maybe we should rewrite it in Rust and compare".
> "Maybe we should rewrite it in Rust and compare" That already happened, almost three years ago. It's an interesting comparison point. The OP contains memory corruption bugs in C++'s standard regex library. If Rust claims to prevent these kinds of bugs, does it actually hold up to scrutiny? One way of testing that is throwing a fuzzer against a regex library written in Rust.
Re: Regex: badly needs fuzzing
#155Earlier quoted context omitted.
> Well, yes if the strawman "all modern C++ written by experts is free from memory safety issues" is what you're countering. Well, I have seen exactly that sentiment. But, more importantly, this isn't exactly an obscure memory safety issue. It's a huge collection of flaws that showed up the instant Dmitry Vyukov threw a fuzzer at it. It's not just "all expertly-written C++ is free of memory safety issues" that this i…
> Well, I have seen exactly that sentiment. Then surely you can provide a reference to it. > it's also a counterexample to "most C++ written by experts doesn't have memory safety issues that matter in practice". This is "most C++ written by experts"? At least you're willing to back off your initial ridiculous assertion somewhat. This one isn't much better though. > I haven't brought up Rust here. Oh come on, you can'…
Re: Regex: badly needs fuzzing
#156The larger question is why every conversation on here even tangentially related to C++, or Go, or almost any programming language for that matter, becomes about Rust. Just because it isn't a commercial product doesn't mean shilling is okay.
We detached this comment from https://news.ycombinator.com/item?id=13601628 and marked it off-topic.
Re: Regex: badly needs fuzzing
#157Earlier quoted context omitted.
> Do you really think a true expert couldn't make a safe C++ regex library? I do believe that a C++ regex library written in reasonable time using normal development practices will have memory safety problems in it. This is based on the real-world experience we have with C++ projects. > Yet another time, I find out you really can't accomplish the task without writing unsafe code, so the compiler really wasn't going t…
> I do believe that a C++ regex library written in reasonable time using normal development practices will have memory safety problems in it. This is based on the real-world experience we have with C++ projects. Me too. I'm guessing the JavaScript RegExp types in Firefox and Chrome are pretty battle hardened at this point though. I submit those as existence proofs that it could be possible. However, I'm sure they've…
It's worth mentioning that the implementation difficulty of data structures in Rust is not representative of the general difficulty of programming in Rust. Just because this is hard doesn't make it a bad language. Rust's philosophy is that you deal with the trouble of writing unsafe code each time you need a new low level abstraction, and when done, you don't have to worry about it again.
Also, writing generic datastructures in C++ without falling afoul of UB, and/or getting destruction semantics right can be quite tricky. Rust ... really doesn't have additional issues here; raw pointers in Rust work the same way as in C++, except they're a tad verbose. The only difference is that in Rust you probably want to provide a safe API, whereas in "freshman C++ datastructures" the datastructure does not have the unsafety neatly encapsulated. This is a hard task in both Rust and C++, especially with generic datastructures.
Writing datastructures isn't really a common task. It's a "simple" task because it's simple in C and C++, but here's no real reason it has to be in Rust. You can write inefficient datastructures in 100% safe Rust without too many problems, much like you can implement datastructures in regular-joe Java. Writing efficient, low-level datastructures can be pretty hard, but like I said it's a rare task so not much of an issue.
http://cglab.ca/~abeinges/blah/too-many-lists/book/ and https://doc.rust-lang.org/nomicon/ are pretty good resources about writing unsafe Rust. The exact boundaries and semantics of unsafe code are still being pinned down so while I do want to improve this documentation I'm waiting for that to happen first.
In general I advise folks to not write unsafe Rust till they are sure that they have a clear grasp of safe Rust. But if you want I can have a look at what you tried and help you improve your design. I'm very interested in making such things more accessible (on one hand, the Rust community doesn't really want to encourage the use of unsafe code, on the other hand, sometimes you need it and it would be nice if it was easier for people to use when that situation arises) so learning what people stumble on is important to me.
> Unfortunately, I don't think they're very concerned about my particular use cases (and maybe they should > > I think all this says is that you don't write very much of the kind of code which benefits from generics. You can dismiss my point of view, but some of us do use them a lot, and it's one of the driving reasons I use C++.
It seems like you're using generics the way you use templates for metaprogramming in C++. I totally get how powerful TMP is (I love to use it myself, though I can get carried away), but be aware that Rust is a different language and you have to approach it differently. It's important to consider the limitations of the system when designing a solution -- if I designed a solution for C++ and implemented it in Rust, I'd hit problems in the last mile and find it very annoying to make it work (using macros or something to fill in the gap). However, if you design the code from the start with Rust's advantages and limitations in mind; you may come up with a different but just as good system. This is something I hit every time I learn a new language. I hit it with Rust, Go, and many years ago, C++. So it may help to approach the language with a fresh mind.
Yes, coherence is painful. I seem to hit coherence issues pretty rarely myself, but they're annoying when they happen. There's work going on to improve these pain points (specialization!), but it's overall not that big a problem.
I think an example of what you tried might help. Preferably a more holistic example, condensed minimal examples tend to hide instances of the XY problem.
> Disclosure: I don't really know what an "overlapping instance" means in this context.
cases where you have more than one implementation that make sense for a given call. C++ solves this by allowing things to overlap and introducing overload resolution rules. Rust solves this by not allowing overlap.
> but I'm guessing the memory foot print would be at least twice what it is in C++. (I should measure that though.)
Go does make extensive use of the stack and has decent escape analysis, so it might not be that bad, really. But measuring it is probably the best way to go here.
> Some other time it's because the standard library doesn't have a trait for a commonly implemented method, so I can't write a generic function to call that method.
Do you have examples? In some cases generic methods are outside the stdlib in different crates, e.g. num_traits.
Re: Regex: badly needs fuzzing
#158Another counterexample to the idea that modern C++ written by experts is free of memory safety issues.
I don't fundamentally disagree with you (any C++ bigger than a screenful of code probably has memory safety issues) but contrary to its reputation, I've find Boost to be of really poor code quality.
Which is telling because it's raison d'etre is quality and it was written by some pretty smart people.
Re: Regex: badly needs fuzzing
#159Earlier quoted context omitted.
How can you say these are considered unacceptable risks to most, when people write so much code in C and C++? These risks are widely accepted and people are trying to mitigate them using various methods. And that's what I'm trying to communicate: they're only unacceptable to pcwalton and the Rust community.
> How can you say these are considered unacceptable risks to most, when people write so much code in C and C++? This argument was very compelling in, for example, 1997. But, nowadays, most code is written in memory safe languages. Choosing to write your next Unix daemon in Go or your next Windows app in C# is not exactly an uncommon choice in 2017. > And that's what I'm trying to communicate: they're only unacceptabl…
I don't know how to explain this more clearly: you are trying to enter an established market and "sell" a product based on its safety capabilities.
But your problem is that the market doesn't think it has a big safety problem, they think they can manage it. And instead of recognizing that and adapting your marketing efforts, you're just repeating the same safety pitch with more examples and details.
How has this been working for you, besides antagonizing the potential "customers"?
Re: Regex: badly needs fuzzing
#160Earlier quoted context omitted.
> I do believe that a C++ regex library written in reasonable time using normal development practices will have memory safety problems in it. This is based on the real-world experience we have with C++ projects. Me too. I'm guessing the JavaScript RegExp types in Firefox and Chrome are pretty battle hardened at this point though. I submit those as existence proofs that it could be possible. However, I'm sure they've…
> It was a weekend learning project, and all I wanted to do was create a freshman level data structure from scratch. It's worth mentioning that the implementation difficulty of data structures in Rust is not representative of the general difficulty of programming in Rust. Just because this is hard doesn't make it a bad language. Rust's philosophy is that you deal with the trouble of writing unsafe code each time you…
> I'm very interested in making such things more accessible
At that point, I simply wanted to implement my own version of something like a statically sized matrix to learn how to manage low level memory. Doing a growable array the right way in C++ involves placement new, explicit destructors, std::move and/or std::swap (and exception safety is a bitch), so I'll agree it would be unfair to expect implementing Vec to be simple. However, you can get a rudimentary matrix working almost trivially. I eventually ended up abusing the unsafe code in Vec to get what I wanted:
fn alloc(size: usize) -> Box {
return vec![Default::default(); size].into_boxed_slice();
}
#[derive(Debug)]
pub struct Matrix {
pub rows: usize,
pub cols: usize,
pub data: Box, // initialized by alloc() above
}
For what it's worth, I would really prefer the equivalent of this C++: template
struct Matrix {
// data lives on the stack
// the type knows the sizes
T data[rows][cols];
};
But that will have to wait for type level integers.> It seems like you're using generics the way you use templates for metaprogramming in C++.
I'm not opposed to TMP in C++, but I really only use it in C++98 to make up for the lack of decltype. In C++11, I don't really need it for what I do. Maybe you and I consider TMP to be different things, but I don't think I was trying to do TMP in Rust. I talked with @steveklabnik about this one already:
fn simplified_example(a: T, b: T) -> T
where T: Copy + PartialOrd
{
if a.abs()
What I learned is that I would need to write my own Abs trait to make this work, and that I would need a Cos, Sin, Exp, Log, and many others to make other similar generic functions work. (I've had a good look at the num crate, and I think it got a lot of things wrong, so that's not an attractive option.) This at least has a work around, but it's tempting to just rest on macros.> [regarding coherence] I think an example of what you tried might help
I think it's completely broken that this is ok:
impl + Copy> Mul for Matrix
while this is not: impl + Copy> Mul> for T
I've read an explanation or two, but this is a binary operator! Why does the order of the arguments matter for coherence here? I can write a macro to work around this, but maybe operator traits shouldn't be restricted with the same logic as other traits.> There's work going on to improve these pain points (specialization!)
You've mentioned that before (at least I think it was you), around the time I was looking at this. I thought specialization had already been accepted, but I haven't stayed all that current. Regardless, how would it help with my binary operators example above (or the generic function above that)?
Anyways, these are all really simple things in C++, and they aren't simple in Rust, and that was my main point a few comments back.