Earlier quoted context omitted.
Why would I want to? Better to explicitly convert the number to a string.
This is something you do often in JavaScript, for example: "You have " + messages + " new messages"
Glorious!
311–320 of 511 posts
I'd love to see someone write a game engine in Rust to compete with the "big boys" like Cry or Unreal. C++ game code can be such a nightmare.
Not going to happen in the next 10 years, everything is built around C++. And tbh I don't see what would games benefit from using Rust instead of C++.
Any time you work in a large team in a corporate environment you want a language that lets you stab yourself in the foot as little as possible.
Earlier quoted context omitted.
Actually, the only real advantage that C has over rust there is the availability of trimmed libcs.
C seems to be going through yet another renaissance. C is a smaller language to learn. There is tons of legacy code even for embedded systems.
There are engineers with 20 years of C programming experience that will still make security errors while handling basic strings. "Small" does not mean "good" and "learning" a language doesn't mean you'll write good code with it.
Earlier quoted context omitted.
> If my script depends on a database connection, I might connect to a database and unwrap() it so the script errors out if the database isn't available. I think that's a bad example, as it is one of those things that can really fail at runtime and which should be properly handled. Even if handling means printing an error message and stopping the process with an exit code - but not crashing. I think unwrap is for thin…
Thats fair. I said script for that reason. A better example would be assert equivalents - if an API could return null (Option) under normal circumstances but you know it can never be null based on how you're using it, unwrap() makes sense. That contract could only be violated if there's a bug in the implementation. If thats the case all guarantees are out the window and usually the best / only thing you can do is to…
I've found that there are a lot of minor bugs in the implementation that, in something client-facing (e.g. not on a server somewhere that can simply be taken out of the load balancing rotation until it restarts or whatever) probably shouldn't crash.
Report and log errors remotely - to be fixed - and skip some logic that relied on those guarantees, but not crash.
> Also in those case (in my experience) having a human-readable error message is rarely useful.
I'll settle for developer-readable, then ;). Panic can format error messages, and itself provides context information (the file and line you mention) as a decent means of reporting fatal errors. Some assertions are obvious enough as to their reason and cause from context - as you say, they don't need a message.
But I've also found taking the 10 seconds or so to think of a decentish error message pays off quite frequently. Even if I'm pretty sure it's unnecessary. Sometimes it may save me only a minute of context switching by telling me exactly what the problem was (instead of roughly describing some assumption made for unknown reasons), sometimes the only way I can make progress is by adding more logging and messaging and reproducing the problem because I couldn't suss out exactly what was happening - and deciding this could take a lot longer than a minute if I know it's hard to reproduce.
Earlier quoted context omitted.
> However it does nothing, and probably cannot, address the security i.e. the impact on my own safety or that of my assets. Sure it can. It actively prevents certain type of errors (buffer overflows, integer overflows), which are prime security exploits. Less exploits == more security.
My standpoint is that: - Less exploits is an improvement in frequency - More security is a question of limiting impact
Earlier quoted context omitted.
Thanks, thats very helpful. I did not know about the minus sign. A polite suggestion - maybe the link marked [-], that takes you to the index, could be labelled "index".
Well, it's not so much that it's an index, it's that when you have a page with only signatures, it feels like an index. There's no redirect, just some JavaScript :)
Earlier quoted context omitted.
Speaking of HTTP clients, just yesterday the person behind Hyper announced their new high-level HTTP client crate: http://seanmonstar.com/post/153221119046/introducing-reqwest
Not sure what to think of that. Does everything have to be async I/O now? How often do you need massive numbers of client connections?
Netty is an asynchronous, event-driven network framework for Java, and it's perfectly possible to expose synchronous blocking abstractions on top of it. The mechanism is pretty simple: the asynchronous framework exposes a future representing the result of an operation, and to provide a synchronous interface you simply block on the completion of that future before returning. Client libraries can handle this for you, providing the interface of e.g. a regular blocking HTTP client on top of Netty async IO.
This approach can be convenient, since it's possible for both synchronous and asynchronous style code to coexist easily in the same application. The application designer can incrementally change parts of the application into asynchronous style as performance needs dictate. For example, you might choose to serve typical small RPC requests using blocking workers in a thread pool, but when you need to stream the content of a large file across the network you could use a separate nonblocking worker pool that interacts with both the file system and network asynchronously.
The ability to interact in a blocking way via futures means that asynchronous facilities can serve both synchronous and asynchronous needs, making them the better choice for most frameworks today. While it used to be the case that async IO frameworks took a performance penalty compared to well-implemented sync IO ones, from what I understand that gap has been closed, and the highest performance frameworks are now all async IO. For example, check out the TechEmpower Web Framework Benchmarks. Most or all of the top performers use asynchronous approaches: https://www.techempower.com/benchmarks/#section=data-r13&hw=...
Earlier quoted context omitted.
Seriously? Rust's error handling is great, and frankly I'm glad that exceptions have gone out of favour. I tried them but they never really delivered their promise. At their best they do is give you nice stack traces. At their worst they make error handling stupidly verbose, they erase the context you need to properly handle errors, and they make it much more difficult to even know which errors can occur! Rust's solu…
I very strongly believe exceptions are a lot closer to optimal than Result is. Exceptions remove the need for inline error checking code and make it possible to implement types with value semantics. You can't have reasonable value types that own resources if you need explicit error checking. The need for explicit error checking makes OOM handling in Rust awkward at best. I've ranted about this side effect before. Als…
With the new trend, you pay up front and go verbose, put more logic at the call site instead of indirecting it away. Go is at the leading edge of that: lots of LOC for boilerplate is OK in Go-land.
I'm more pragmatic with my error handing methods: I mostly care about whether I can eliminate a class of errors altogether, and secondarily what debugging implications are presented. I don't have a strong opinion on verbosity although I have followed the trend in that respect towards more call site logic.
Earlier quoted context omitted.
Are you confusing SaferCPlusPlus with a different library? SaferCPlusPlus is a new library that makes it practical to stick to a memory safe subset of C++ (i.e. no native pointers, no native arrays, no std::array , no std::vector , etc.). Using the SaferCPlusPlus library to replace all uses of C++'s unsafe elements does result in code that is as memory safe as Rust, or any other modern language. The main shortcoming…
Create a vector. Push an element onto it. Take a reference to that element with operator[]. Clear the vector. Call a method on that dangling reference. Create an object on the stack. Return a reference to that object. Call a method on that reference. Create a vector. Push an element onto it. Call a method on that element that clears the vector and then calls another virtual method on itself, via the this pointer. Acc…
> Create an object on the stack. Return a reference to that object. Call a method on that reference.
References are one of the unsafe C++ elements that SaferCPlusPlus is intended to be used to replace [1].
> Create a vector. Push an element onto it. Call a method on that element that clears the vector and then calls another virtual method on itself, via the this pointer.
Yes, that series of operations is safe. A related example from the "msetl_example.cpp" file:
typedef mse::mstd::vector vint_type;
mse::mstd::vector vvi;
{
vint_type vi;
vi.push_back(5);
vvi.push_back(vi);
}
auto vi_it = vvi[0].begin();
vvi.clear();
try {
/* At this point, the vint_type object is cleared from vvi, but it has not been deallocated/destructed yet because it
"knows" that there is an iterator, namely vi_it, that is still referencing it. At the moment, std::shared_ptrs are being
used to achieve this. */
auto value = (*vi_it); /* So this is actually ok. vi_it still points to a valid item. */
assert(5 == value);
vint_type vi2;
vi_it = vi2.begin();
/* The vint_type object that vi_it was originally pointing to is now deallocated/destructed, because vi_it no longer
references it. */
}
catch (...) {
/* At present, no exception will be thrown. We're still debating whether it'd be better to throw an exception though. */
}
I agree with the gist though. This kind of thing should be prevented at compile time. Rust has an excellent static analyzer/enforcer built into its compiler. Arguably, it would be a service to the community to unbundle it from the Rust compiler and make it available for application to C++ code as well. Arguably.> Accidentally share a vector between threads. Race push_back() and remove().
SaferCPlusPlus addresses the sharing of objects between asynchronous threads [2]. A particular shortcoming of C++ wrt to object sharing is that it doesn't have a notion of "deep const/immutability".
> Additionally, the pointer registration mechanism that that library uses has a runtime performance cost worse than a GC write barrier (because it incurs writes on reads).
Um, yeah, modern code should try to avoid the use of general pointers (and generally does). Most modern languages don't provide general pointers. SaferCPlusPlus makes them safe and slow (and available for easy porting of legacy code). When writing new code you would instead, when required, use one of the faster pointer types available in the library.
Don't interpret SaferCPlusPlus as an assertion that C++ is a uniformly better language than Rust or other modern languages. It's more of a suggestion that C++ and existing C++ code bases can be salvaged to a greater degree than one might think.
[1] http://www.codeproject.com/Articles/1093894/How-To-Safely-Pa...
[2] http://www.codeproject.com/Articles/1106491/Sharing-Objects-...
Earlier quoted context omitted.
> Rust cannot make any latency guarantees either. Reference counting and its lifetimes also have pathological cases, ie. worst-case, an object can reference the entire heap which will take time proportional to the number of dead objects to free. Rust doesn't use reference counting by default. Refcounting is very rare in Rust, much more rare than it is in C++. Most large C++ codebases I've worked with have thrown in t…
Trees don't have to be refcounted in Rust. Single-ownership trees are possible. As long as they don't have backpointers. Backpointers are a problem under single ownership.