6 ms·
Why struggling using qsort? std::sort from C++ is much better in terms of usability and performance.
by Panzerschrek 10mo ago
Why struggling using qsort? std::sort from C++ is much better in terms of usability and performance.
- pjmlp 10mo agoBecause some people will never move beyond C, no matter what.
- tliltocatl 10mo agoPeople will never move beyond C (among other reasons) because C allows precise control over memory allocation. Closures and precise control over memory allocation doesn't play very well together.
- spacechild1 10mo ago> Closures and precise control over memory allocation doesn't play very well together. How so? In C++ a lambda is just a regular type that does not allocate any memory by itself. You have in fact precise control over how/where a lambda is allocated.
- flohofwoe 10mo agoTrue, but once a capture needs to survive the parent function scope you'll need to store it somewhere, either via a std::function object which has opaque rules on whether a heap allocation happens or via your own std::function implementation where you define the heap allocation rules but then will have to face discussions about why you're rewriting the stdlib ;) Any C implementation of capturing lambdas has the same problem of course, that's why the whole idea doesn't really fit into the C language IMHO.
- fuhsnn 10mo agoI did a version with explicit capture objects for fun: https://github.com/fuhsnn/c-extensions#extended-capture https://github.com/fuhsnn/c-extensions#extended-capture Basically, with each capturing lambda, a context type _Ctxof(fn) is created that users can then declare on stack or on heap themselves.
- uecker 10mo agoInteresting! Can you tell me about your experience? How does it compare to the versions in N3654? (where this idea comes from) https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3654.pdf https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3654.pdf
- fuhsnn 10mo ago- Non-capturing isn't that much simpler to implement for the front-end, because they still need to distinguish between a file-scope name or a shadowing local in parent function. And once you have the code to do that distinction, it's not that far away from implementing captures. - From implementor point of view I just don't like the idea of a new category of function qualifiers, so I used "_Wideof(int(void))" over "int(void) _Wide", and "int fn({...}, void)" over "int fn(void) _Closure/_Capture(...)". - During prototype scope of the inner function, parameters may have VM type that reference from parent's local scope, so the capturing (or not) effectively start at prototype scope, earlier than C++'s model. My syntax has capture clause right before parameters so it is somewhat manage-able in one pass; for function qualifier syntax the parser probably need to either delay semantic checking the VMs or skip ahead to find _Closure/_Capture before processing the parameters. - Both N3654-example6 and N3694-4.4.6 implicitly create capture context on stack then provide reference to it (N3654 with &_Closure(), N3694 with inner function's name). My version is lower level in that only the type of capture context (_Ctxof(fn)) is implicitly created, users then call a helper (modeled after va_start) to initialize the context object. I believe it also reduces surprises from by-value captures, since users clearly see where they initialize a context object relative to local variable changes. - Sans syntax, N3654's "specified argument" is pretty close to my implementation, just need to change the source of context pointer from r10 to the argument in function prologue. - I implemented wide function pointers as generalized "function pointers with context pointer pushed in r10", so it's also possible to make wide pointers from regular functions, they'll just be called with an extra nullptr in r10. I think it's more flexible this way. What I did was mostly "the compiler will need these anyways" so should be adaptable to whatever WG14 settled on, or if I ever want to implement C++11 lambda.
- 10mo ago
- pjmlp 10mo agoUrban myths by people frozen in time, systems programming languages predate C by a decade, and it isn't as if the world stopped outside Bell Labs in the 1970's.
- tliltocatl 10mo agoWhich systems (as in zero-runtime) language would you choose if not C (even if we disregard the fact that no SoC vendor support anything but C)? - Ada? Many cool features, but that's also the problem - it's damn complicated. - C++ combines simplicity of Ada with safety of C. - Rust and Zig are only ~10 years old and haven't really stabilized yet. They also start to suffer from npm-like syndrome, which is much more problematic for a systems language. - ATS? F#? Not all low-level stuff needs (or can afford) this level of assurance. - Idris? Much nicer than ATS, but it's even younger than Rust and still a running target (and I'm not sure if zero-runtime support is there yet). I mean, yes, C is missing tons of potentially useful features (syntactic macros, for one thing), but closures are not one of them.
- tialaramex 10mo agoIt is insane to assert that Rust hasn't "really stabilized yet" in comparison to C, a language which has been replaced twice (as C17 and C23) after Rust 1.0
- 1718627440 10mo agoExcept that those are more like bug fixes, it's unlikely to have something newer than C11 and most are still on C99.
- pjmlp 10mo agoShow us that you haven't read ISO C documents without telling us.
- 1718627440 10mo ago
- 1718627440 10mo agoBecause C is a much nicer language than C++ by some measures.
- dfawcus 10mo agoNah - more that a lot of commercial code is written in it; and it doesn't make sense to replace (or rewrite) it at this time. For example, I'm maintaining some 20 year old C code, which the employer adopted around 10 years ago. It will likely stay in use at least until the current product is replaced, whenever that may be.
- 1718627440 10mo agoLet me rephrase that: I feel myself addressed by "some people will never move beyond C, no matter what" and I prefer C over C++, because it is a much simpler language. Each time I am leaving the cozy world of C and write C++ I am annoyed and miss things.
- pjmlp 10mo agoNah, C++ gives you the safety tools, even if with some flaws, that WG14 does not have any interest to ever add to C.
- flohofwoe 10mo agoAnectodal and probably my bubble, but quite a few people had moved from C to C++ long time ago, but then got fed up with where modern C++ is heading (mostly around C++14 and C++17) and went back to C.
- deleted 10mo ago[deleted]
- pjmlp 10mo agoExcept it doesn't offer the safety alternatives that C++ has, thus it is a big unsafe bunch of code. Using C++ doesn't mean having to use the whole standard. Now if C type safety actually was like Modula-2, Object Pascal or Zig, that would not be as bad.
- flohofwoe 10mo ago> Except it doesn't offer the safety alternatives that C++ has, thus it is a big unsafe bunch of code. C++ adds more new unsafe concepts on top of C than C ever had though ;) (see std::view, std::range or good old iterator invalidation - at least in C the unsafety is in your face and not hidden under layers of stdlib code)
- flohofwoe 10mo agoFWIW, when the C compiler has access to the qsort implementation body and the comparer function like the C++ compiler has, it will also stamp out a specialized version that will in most cases be identical with the C++ compiler output for std::sort (assuming it implements the same sorting algorithm as C's qsort). That whole 'zero cost abstraction' idea is not unique to C++ since all the important work to make the 'zero cost thing' happen is performed down in the optimizer passes, and those are identical between C and C++.
- kccqzy 10mo agoYeah but C++ encourages you to put things into templates which are inside headers, so of course the implementation body is exposed to the compiler all the time. Whereas a C compiler usually won’t have access to the qsort implementation body.
- Panzerschrek 10mo agoI see no inlining of qsort in at least two major compilers: https://godbolt.org/z/59xehaqnv https://godbolt.org/z/59xehaqnv.
- flohofwoe 10mo agoYes, that's why C++ std::sort is usually recommended over C qsort. But either compiling with -flto or providing your own fully inlineable qsort should do the trick.
- tialaramex 10mo agoIf you care about performance and are willing to use a different programming language surely it would make more sense to use Rust's unstable sort ?