5 ms·
C++26: The Oxford Variadic Comma
- lasgawe 7mo agolearned something new. thanks for the article.
- mFixman 7mo agoI used to slay with this in code golfing competitions from TopCoder, where you had to implement a function to solve a particular problem, thanks to C pointer maths and the gcc generally putting function arguments in order in the stack. Turns out, these two are equivalent in practice (but UB in the C++ standard): double solve(double a, double b, double c, double d) { return a + b + c + d; } double solve(double a ...) { return a + 1[&a] + 2[&a] + 3[&a]; }
- camel-cdr 7mo agoK&R syntax is -1 char, if you are in C: double solve(double a,double b,double c,double d){return a+b+c+d;} double solve(double a...){return a+1[&a]+2[&a]+3[&a];} double solve(a,b,c,d)double a,c,b,d;{return a+b+c+d;}
- mananaysiempre 7mo ago> Turns out, these two are equivalent in practice Not in the x86-64 SysV ABI they aren’t. The arguments will be passed in registers (yes, even the variadic ones), so how your compiler will interpret 1[&a] is anybody’s guess. (For me, x86_64-unknown-linux-gnu-g++ -O2 yields, essentially, return a+a+a+a; which is certainly an interpretation. I’m also getting strange results from i686-unknown-linux-gnu-g++ -O2, but my x87 assembly is rusty enough that I don’t really get what’s going on there.)
- Sharlin 7mo ago> return a+a+a+a; which is certainly an interpretation. Zero is the only valid index of &a, so I presume the compiler just assumes that all the indexes in 1[&a] + 2[&a] etc must be zero. Even though they're in this case compile-time constants – the optimizer could check but why bother given that it's UB anyway. I assume modern C/C++ compilers have some flag to diagnose indexing that's known to be OOB at compile time.
- mananaysiempre 7mo agoI’m so used to sticking -Wall in my compilation flags the moment I write a build script that I didn’t realize it wasn’t there for this quick experiment. Yes, thank you, there are indeed diagnostics once you ask for them: test.cpp: In function ‘double solve(double, ...)’: test.cpp:4:20: warning: array subscript 1 is outside array bounds of ‘double [1]’ [-Warray-bounds=] 4 | return a + 1[&a] + 2[&a] + 3[&a]; | ~~~~^ test.cpp:3:58: note: at offset 8 into object ‘a’ of size 8 3 | extern "C" __attribute__((noinline)) double solve(double a, ...) { | ~~~~~~~^ [repeat twice more for the other two accesses]
- jcranmer 7mo agoExample compiler explorer view: https://godbolt.org/z/b5z3q1616 https://godbolt.org/z/b5z3q1616 Clang does the sensible thing with UB and just returns poison (a form of undefined value) in both cases, which manifests as do nothing on x86-64 and load a zero value on i386, because you need to push something on the stack and fldz is one of the cheapest ways to push something. Meanwhile, gcc is in both cases for the UB variant returning a + a + a + a; FWIW, going back through older gcc versions, it seems i386 gcc stops implementing 'add the arguments' in version 11.1, although it's not until 15.1 that it has a sensible assembly for 'a + a + a + a'. The x86-64 gcc version is broken in 4.0 (where it stops copying the register arguments to the stack when va_start isn't called, I guess). Then it's adding xmm0 to the top 3 values on the stack until 11.1, when it's adding 'a + a + a + a', although not sensibly until version 15.1.
- Joker_vD 7mo agodouble solve(double a[]) { return 0[a] + 1[a] + 2[a] + 3[a]; } solve((double[]){1, 2, 3, 4}); The cast in the invocation can be macro-ed away. And the best thing is, the actual stack layout and data movement/shuffling is pretty much identical to the approach with <stdargs.h>, and with no UB or compiler intrinsics.
- kevin_thibedeau 7mo agoThat's a compound literal, not a cast.
- maccard 7mo ago>turns out these two are equivalent in practice Err no; https://gcc.godbolt.org/z/sW3ea58oc https://gcc.godbolt.org/z/sW3ea58oc They're equivalent on GCC.
- advael 7mo agoThis seems pretty good to me just on the level of trying to read C as someone using C++. Parameter packs and variadic templates are easily the most confusing syntax in C++ and cleaning it up is... very welcome
- jkaplowitz 7mo agoHats off for using "..." in your comment immediately after a valid identifier word and with no comma in between, given the topic of the article.
- advael 7mo agoHats off for noticing. Not to be taken for granted in an increasingly skimming-oriented world
- PaulDavisThe1st 7mo agoThere remains the problem of defining what the meaning of ...is, is.
- advael 7mo agoMaybe in another 20 years, ... we will understand
- throwaway2027 7mo agoC++ got too complicated after C++23 I went back to C.
- Conscat 7mo agoNo offense intended to your perspective, but I do find it a little amusing that C++23, which was generally considered a disappointingly small update due to COVID complications, was the breaking point in complexity.
- FartyMcFarter 7mo agoYou can always restrict yourself to a subset of C++ that takes advantage of RAII (resource handling is extremely painful in C), and get performance benefits like move semantics, without the insanely complex stuff. I love C, but C++ has worthwhile advantages even if you heavily restrict which features you use.
- mianos 7mo agoI do this and my C++ is really like python to code in. But, if you work in a team, there will always be a bunch of people who come in and start using all sorts of exotic shit for their resume or hobby interest.
- Conscat 7mo agoSimply by asserting "we support MSVC", most `exciting` C++ will never be touched in a codebase.
- jjgreen 7mo agoC is the new vinyl.
- staplung 7mo agoOf course since the old syntax is merely deprecated and not removed, going forward you now have to know the old, bad form and the new, good form in order to read code. Backwards compatibility is a strength but also a one-way complexity ratchet. At least they managed to kill `auto_ptr`.
- Conscat 7mo agoPyCuda 2024, used fairly often in certain industries, still contains `auto_ptr` ;-;
- hrmtst93837 7mo ago[flagged]
- tialaramex 7mo agoSeveral times now C++ enthusiasts and indeed the committee have been told the way forward is the "Subset of a superset" that is, Step 1. Add a few new things to C++ and then Step 2. Remove old things to make the smaller, better language they want. Once they've obtained permission to do Step 1 they can add whatever they want, and in a few years for them it's time to repeat "Subset of a superset" again and get permission for Step 1 again. There is no Step 2, it's embarrassing that this keeps working.
- vlovich123 7mo agoI think Rust has shown a way to remove deprecated interfaces while retaining back compat - automated tooling to migrate to the next version and give a few versions for a deprecated interfaces to stick around at the source level.
- jjmarr 7mo agoC++ almost never removes features because of the ABI compatibility guarantees. Programs compiled with older versions of the standard can be linked against newer versions. This is allegedly because in the 80s companies would write software, fire the programmers, and throw the source code away once it compiled.
- zlfn 7mo agoC++ seems to be constantly getting complicated. If the major version were to change, there wouldn't be any need for backward compatibility with the existing code, and it would have been okay to delete that syntax while creating an automatic formatter.
- dnmc 7mo agoAre you suggesting we move to C++++?
- zlfn 7mo agoIt's already there. It's called C#
- HackerThemAll 7mo agoWell, C# also has its quirks already. Like the crippled finalizers which are never to be used. If the IDisposable interface had been correctly designed, finalizers could become be the "public void Dispose(void)". Or the manual passing of Task in case of async methods, which is... kinda smelly.
- tialaramex 7mo agoIt's possible you didn't realise, but C# is sometimes said to be named that way because # is the symbol you get if you draw ++ small and then on the line below ++ again. Hence C++++ All languages have some spikier edges, there are no languages I know where I think "Well, even if we could start over I have no idea how to improve this". What's notable about C++ is just how rich that "could do better" seam is, so very many of their defaults are wrong, so many of their keywords are the wrong word, so many of their standard library features are allowed, sometimes even mandated to be crap.
- HackerThemAll 7mo agoI think you meant to get that to the original poster, who seems to imply C# is the flawless, bestest incarnation of C\+\+(\+\+)+.
- HackerThemAll 7mo agoYes, but no. I learned C++ in '90s when it was C with classes and some other noise added by Stroustrup. During the some 25 years that followed it had became a mess that's insanely hard to work with. I'm not going back to this language. I prefer plain C or Rust, leaning towards Rust when I fully comprehend the lifetime and borrow checker. Or when I have the luxury of having a GCed runtime, then the .NET with its easiest C# language with wonderful abundance of great libraries is the best choice. Nobody was ever fired for using .NET (for right purposes).
- PaulDavisThe1st 7mo agoTiring how often this needs to be said, but if you want "C with classes", you can just use C++ that way. I've been using C++ for more than 30 years (I added thread_local to Cfront back in the early 90s), and while the language has grown dramatically in that time, there is fundamentally nothing that would prevent me from writing "C with classes" using the modern version. I don't do that because I also like RAII, and polymorphism, and operator overloading and ... I've never used .NET and could not imagine any scenario under which I would. The libraries that matter to me are mostly written in C or C++ and there are more of them than I'd ever need, mostly.
- QuadmasterXLII 7mo agoLanguages are both read and written, restrictions like OP is pining for are fundamentally for reading. As such, it is not terribly helpful that they can opt in to restrictions when writing.
- PaulDavisThe1st 7mo agoWhat you read is what was written.
- zabzonk 7mo ago> nothing that would prevent me from writing "C with classes" using the modern version. Or indeed "C without classes", just with some extra type-checking. And of course K&R used Stroustrup's C++ compiler to build and test the code for TCPL 2nd Ed.
- blueaquilae 7mo agoI'm far from C++ but reading this article confused be, from the form to the impact to the dead link https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1219r2.html https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p12... I guess that's a preview how C++ require a lifelong commitment.
- tialaramex 7mo agoThat should probably link https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1219r2.html https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p12... The difference being that P1219R2 was actually a revised proposal from 2019 not 2021.
- rusakov-field 7mo agoClarity and Elegance of Syntax > Backwards compatibility. In my opinion anyway. C++ feels so bloated these days.
- useftmly 7mo ago[dead]
- flqn 7mo agoThis is a good change. Potentially ambiguous to read syntax is being made clearer in a way that harms no previous code substantially. I sometimes wonder if the comments that say nothing more than "C++ is too complicated" are from people who use it regularly, much less people who are even commenting on TFA
- saghm 7mo agoI don't fully understand the connection between your two paragraphs. It's not inconsistent for the language to be too complicated for it to be a good change. I'm also not totally convinced that someone not using a language regularly means their view on it being too complicated must be invalid; I would fully expect someone who views it as too complicated to try to avoid using it, and there are enough people doing that, it might be a cause for concern. That doesn't necessarily mean they're right, but without further context it also doesn't mean their opinion isn't relevant.
- paulmooreparks 7mo agoNote to the author of TFA: The moment I get a sign-up modal on any site, I close the tab and move on.