8 ms·
Proposal for C23: Improve type generic programming [pdf]
- FrozenVoid 6y agoC needs operator overloading. Something like this: https://github.com/FrozenVoid/Infodump-DB/blob/943900c2dbf2e9b41d00065c3ee29af8ccf8efbc/programming/c/_Operator.txt https://github.com/FrozenVoid/Infodump-DB/blob/943900c2dbf2e...
- pantalaimon 6y agoNo, I'd say that operators will always result in a primitive operation is actually a feature - everything more complex warrants a proper function.
- HexDecOctBin 6y agoI'd say they should probably go the other way, defining even built-in operators like: operator+(int a, int b) __gcc_internal_int_sum(a, b) This way, we can change (through overriding) the way these operations work (rounding, overflow, coercing, etc.), without having to define non-idiomatic functions to do so. A lot of undefined behavior can be made user-defined this way.
- gmueckl 6y agoThere should be a middle ground. The main issue with operator overloading is that every overload exists in the global scope. Thus, you get issues and surprises with unknown or competing overloads. Sometimes, a workable solution would be to have overloads restricted to a kind of named scope that the calling code can enter explicitly. Maybe something like operator_context(mz_vector_ops) { ... } which makes all operators defined in the context of my_vector_ops apply to expressions within the block, but nowhere else.
- FrozenVoid 6y agoConsider arbitrary precision, rationals, interval arithmethic, countless algebraic types, matrices, vectors with all of them requiring typing and composing long functions versus intuitive formula: mpz_mul(res,x,y); mpz_mul(res,res,z); vs x*y*z; ```
- jstimpfle 6y agoThe following style is much better: v3 r = Add_v3(v, w); v4 w = Scale_v3(r, 1.0); You can definitely write a little 3D graphics backend this way. C's lack of operator overloading can be annoying for some tasks, however I still like to use C for almost everything to this day, because of the lightness of going through old code and seeing instantly what happens - never have to run any type resolution in my head. And importantly, _knowing_ that I don't have to do this. Because I might almost never have to do this in cleanly written C++ code, but how do I know?
- jjoonathan 6y agoMath libraries are an exception. You want this: d + A*B*(c*(a*b)) Not this: vector_add(mv_multiply(matrix_multiply(A,B),vector_dot(a,b)*c),d)
- jcelerier 6y agoso are expression grammar libraries, etc
- wtetzner 6y agoIt'd be cool to have the Haskell feature of putting backticks around a binary function so you can use it infix, e.g.: ((A `mmul` B) `mvmul` (a `vdot` b) * c) `vadd` d Still not as nice as operators, but not terrible either.
- flohofwoe 6y agoYou can get this with clang's vector extension (https://clang.llvm.org/docs/LanguageExtensions.html#vectors-and-extended-vectors https://clang.llvm.org/docs/LanguageExtensions.html#vectors-...), and this would make a lot of sense to add to the C standard. IMHO vector math is about the only place where operator overloading is acceptable in C++.
- fctorial 6y agoWhat you actually want is function overloading, which C can't support since C functions map directly to elf symbols, and all assembly functions are vararg with all arguments being WORDs. (That's how it is in elf, *nix and x64, don't know much about other platforms)
- FrozenVoid 6y ago_Generic macros provide similar functionality to function overload(which in C++ involves name mangling, that will never be accepted for C) https://en.cppreference.com/w/c/language/generic https://en.cppreference.com/w/c/language/generic
- lldbg 6y agoIn C++, name mangling is used to solve this issue
- mjburgess 6y agoYou don't need a vtable for overloading; that is just runtime polymorphism ("ad hoc polymorphism". Function overloading can be done compile time, eg., parametrically: add(3.0, 1.0) -> compile to add_float32_float32 add(1, 2) -> compile to add_int32_int32
- fctorial 6y agoAs I said, `add` function in C maps to a symbol named `add` in assembly. You're demangling the function name, which is what C++ does.
- mjburgess 6y agoSure, you're right. I guess we'd need C to have a special syntax to compile in something like a vtable add_f32_f32(x, y) calls add(MAGIC_NO, x, y) and add has a big switch on MAGIC_NO for selecting implementation... You'd need a keyword for this, "multi int add(int a, int b) ..."
- 6y ago
- squid_demon 6y agoPlease leave C alone. Thanks much.
- Jtsummers 6y agoThanks to the sheer number of C programs, no compiler supporting later C standards will drop support for prior standards unless it's explicitly targeting the later standard and that standard is fundamentally breaking with earlier ones. And even then, the major players won't because they still have to support every program ever written in C. So any changes to C at this point will not break your ability to use whichever prior C standard you happen to be interested in.
- emteycz 6y agoExcept when you come to a new company and find out they're using the new glory all over the place and insist you do too.
- Jtsummers 6y agoWell, if you join a team you join whatever they're using. Which may not even be C. If you want control, you have to lead the team in the company or run your own company. That's part of being a "company man". You forfeit control over the kinds of things you work on and many decisions about what and how they're made unless you have the right ear or the right level of authority.
- ephaeton 6y agoThere's a time and place for everything. Regarding the time, it is and has been the time for this since lisp emanated. But C is not the place, IMO. I don't want to be left to wonder about sizeof(anything) in C. "Lisp Programmers know the value of everything and the cost of nothing." C programmers ought to know the cost and sizeof everything... I hope the committee sees it like this as well. I also believe the feature (auto) makes sense for C++ with its verbose and lengthy types nobody but your compiler cares about (say, e.g., multimap::equal_range). For C? Get out of here.. this passes, and suddenly zig becomes a whole lot more interesting ;) (but zig also has type inference you say? Well, it's a consistent proposition, and not a tacked-on "feature".)
- scatters 6y agoC has VLAs, so sizeof is a runtime operation. That's already more complex than C++, where sizeof is fixed at compile time.
- flohofwoe 6y agoVLA has been "dropped" from C11 though (made optional), so it's essentially been degraded to a compiler-specific language extension. IMHO VLAs were a "misfeature" that shouldn't have slipped into the standard in the first place.
- wahern 6y agoWith some slight tweaking variable modified types are the simplest and cleanest way forward to supporting arrays/slices as function parameters. void foo(size_t n, char buf[n]) { size_t m = sizeof buf; } In a saner world n and m should be equal, but in a cruel twist it doesn't do what you'd expect. I don't understand why the committee crippled the semantics here when adding VLAs and variable modified types. Never too late to fix things, though.
- scaramanga 6y agoThat's interesting. Can you elaborate on why?
- qppo 6y agoType inference is great and undeserving of the "bah humbug" type comments. Not a fan of it in function return types but that's easy to avoid in code review or linting (both of which you need plenty in C). The closure proposal is much more interesting. I skimmed the discussion and it points out many of the benefits and some syntax proposals, but I'm wondering about memory management. In C++ a lambda may not be convertible to a function pointer if the captured context is non zero sized, and if the captured context is larger than the size of a pointer it must use some kind of dynamic allocation. C++ has scoped destructors, making implementation of that relatively straightforward (free the context when the lambda goes out of scope), but what would C require? Defer statements? Require a free() without matching call to malloc? Closures in C are still possible using void* as a user context, which is common both for closure semantics in libraries as well as implementing closures in languages transpired to or interpreted in C. The memory management is explicit, the types remain explicit (except for the closed over context), albeit a bit verbose. As much as I love functions as types and programming with them I'm confused how this is a positive feature for C, which lacks some of the semantics that other languages have making closures sensible.
- jcranmer 6y agoSo this proposal retains the C++ feature of not allowing you to do anything with the captured context. Semantically, it's as if you created the captured variables as new function-local variables when you initialized the function call, and the wording makes it UB to modify the captured variables via a pointer. Where the capture context lives in memory and how it is allocated and deallocated is not precisely specified by the specification, but there specification does permit it to be handled via C++-style scoped destruction. That C has no way for you to manually write this code does not preclude implementations from using that logic internally, especially since most C compilers are also C++ compilers and handling C lambdas as identically to C++ lambdas as possible would have some benefits.
- MauranKilom 6y ago> In C++ a lambda may not be convertible to a function pointer if the captured context is non zero sized, and if the captured context is larger than the size of a pointer it must use some kind of dynamic allocation You are mixing things up here. A lambda will never require memory allocation, regardless of its size: https://godbolt.org/z/Mebn4h https://godbolt.org/z/Mebn4h std::function can't get around memory allocation for sufficiently large functor objects, but that is a matter of how libraries implement type erasure for functors and has nothing to do with the lambda expressions of the core language.
- favorited 6y agoIn the section on lambdas, there is discussion of the "Objective-C blocks" language extension alongside C++ lambdas. They missed that the extension is to C, not Objective-C. I'm not suggesting they standardize Clang's language extension, but I think it's worth noting that a similar feature has actually been implemented for the C language itself, rather than a higher-level one.
- pjmlp 6y agoGiven WG14 views on existing practices, it also fails me why they haven't looked into it.
- rurban 6y agoI'm all for it. auto, simple lambda and closures. The syntax also looks sane.