Earlier quoted context omitted.
Still, there are cases where fall-through can be useful: int remaining = length % 4; switch (remaining) { case 3: h ^= (data[(length & ~3) + 2] & 0xff)
Usually I would just factor out the guts of the expression into a little closure in that case. (let f = |x| h ^= ... x ...) LLVM should inline it just fine, and it'll save you typing.
Things Rust shipped without
181–190 of 330 posts
Re: Things Rust shipped without
#182Earlier quoted context omitted.
~20 years of using various combinations of C and C++, and i never knew you could take the address of a label! reminds me of computed GOSUBs from my basic days :)
And they say C is a simple language... :) To be fair, I've seen code like this exactly once.
Re: Things Rust shipped without
#183Earlier quoted context omitted.
Threads aren't that slow on Linux. The main advantage of M:N threading as implemented in Go over 1:1 is that spawning is fast and doesn't use much memory, because you can avoid the syscall and only a small (initial) stack is required. Rust can't do the latter because it's not GC'd. Even if it could, many real-world servers actually do non-trivial work in their threads, so the cost of spawning a thread is dwarfed by t…
For servers that primarily speak RPC or HTTP, do you foresee Rust going thread-per-request or something more callback-y?
There is a Rust library called "mio" which provides a lot of the plumbing for such systems: https://github.com/carllerche/mio.
The path forward is likely going to involve adding a way to build cheap state machines (call them generators or async/await) with a clean syntax and giving mio hundreds of thousands of reusable instances.
Re: Things Rust shipped without
#184Earlier quoted context omitted.
Well, you generally don't, because Duff's Device isn't generally regarded as a good idea anymore, in my understanding: > It turns out that with branch predictions and the relative speed of CPU > vs. memory changing over the past decade, loop unrolling is pretty much > pointless. http://lkml.iu.edu/hypermail/linux/kernel/0008.2/0171.html
Still, there are cases where fall-through can be useful: int remaining = length % 4; switch (remaining) { case 3: h ^= (data[(length & ~3) + 2] & 0xff)
Re: Things Rust shipped without
#185Earlier quoted context omitted.
What the parent said still applies in your case. You just make a wrapper function that does the cleanup. I have used this pattern many times: static int foo_impl(int arg, int **resource1, int **resource2) { *resource1 = (int *)malloc(sizeof(**resource1)); if (*resource1 == NULL) return EXIT_FAILURE; /* Do something with resource1 (omitted)... */ *resource2 = (int *)malloc(sizeof(**resource2)); if (*resource2 == NULL)…
I know it is just an example to illustrate the point but this seems to have a bug in it: resource2 won't be initialized if the function fail to allocate resource1 so resource2 will be null when the code enters the deallocation condition. A way to fix it would be to return different failures for every allocation and to use a switch without a break to clean up, something like: switch (ret) { case EXIT_SUCCESS: free(res…
Re: Things Rust shipped without
#186Earlier quoted context omitted.
> Which is barely enough to say that Rust is hugely different than just #include-ing C files. Well, sure, if you want to get fancy enough you can make a module system out of #include. (Your code snippet isn't enough because it doesn't replicate privacy or imports.) But replicating something approximating Rust's module system with "#include plus other stuff" doesn't show that Rust's module system is "just #include". >…
> For example, consider math.h. If your program is using one function (say, sin) from math.h, you have to parse all the prototypes in math.h. (And if you have inlined functions or templates in the header files, you have to parse those too!) Isn't this pretty much a solved problem with precompiled / pre tokenized headers? PTH are language / arch / compiler agnostic. http://clang.llvm.org/docs/PTHInternals.html
Re: Things Rust shipped without
#187Earlier quoted context omitted.
What the parent said still applies in your case. You just make a wrapper function that does the cleanup. I have used this pattern many times: static int foo_impl(int arg, int **resource1, int **resource2) { *resource1 = (int *)malloc(sizeof(**resource1)); if (*resource1 == NULL) return EXIT_FAILURE; /* Do something with resource1 (omitted)... */ *resource2 = (int *)malloc(sizeof(**resource2)); if (*resource2 == NULL)…
I know it is just an example to illustrate the point but this seems to have a bug in it: resource2 won't be initialized if the function fail to allocate resource1 so resource2 will be null when the code enters the deallocation condition. A way to fix it would be to return different failures for every allocation and to use a switch without a break to clean up, something like: switch (ret) { case EXIT_SUCCESS: free(res…
Re: Things Rust shipped without
#188Earlier quoted context omitted.
Why "might as well"? Things can be optimal in some places and suboptimal elsewhere.
Consistency is valuable. If some blocks have different rules to other blocks that's a real downside.
Re: Things Rust shipped without
#189I don't get why those are bad? - random-access strings - auto-increment operators
i += ++i; what should be the result ? what is the result in C++ ? (undefined)
1. It could be a compiler error. The existence of certain operators doesn't mean they can be combined arbitrarily.
2. Sequence points could be defined differently, allowing for such a convoluted line. This would likely hurt performance, as the compiler would have fewer operations to reorder in each sequence point.
Typically, increment and decrement are just syntactic sugar. I don't mind if a language lacks them, but I can see why people like them. A convoluted example of UB in C++ is not a good argument against having them.
Also: In C++, overloaded operators are function calls, and function calls are sequence points. So if i is an object, the behavior is defined. That said, it would still be bad code. :)
Re: Things Rust shipped without
#190> goto (not even as a reserved word) I haven't done this for a while, but once upon a graduate program I wrote a compiler from a made-up-language (MUP) to C. MUP had some strange control structures, and if C did not have "goto", it would have been a lot more difficult to implement those structures. Since then, I have always thought languages should have a "goto" statement that human-written code is not allowed to use…
I don't think I've written a goto since the 1970s, and I've written a lot of code since then. If you need to bail out of something in the middle, make it a function.