UmbralRaptor changed the topic of #kspacademia to: https://gist.github.com/pdn4kd/164b9b85435d87afbec0c3a7e69d3e6d | Dogs are cats. Spiders are cat interferometers. | Космизм сегодня! | Document well, for tomorrow you may get mauled by a ネコバス. | <UmbralRaptor> egg|nomz|egg: generally if your eyes are dewing over, that's not the weather. | <ferram4> I shall beat my problems to death with an engineer. | We can haz pdf
egg|cell|egg has quit [Ping timeout: 204 seconds]
e_14159_ has joined #kspacademia
e_14159 has quit [Ping timeout: 378 seconds]
<_whitenotifier-a3da> [Principia] vladtcvs opened issue #2383: "No active engines, falling back to RCS" - https://git.io/Je1ri
<_whitenotifier-a3da> [Principia] vladtcvs edited issue #2383: "No active engines, falling back to RCS" - https://git.io/Je1ri
<_whitenotifier-a3da> [Principia] vladtcvs edited issue #2383: "No active engines, falling back to RCS" - https://git.io/Je1ri
<_whitenotifier-a3da> [Principia] Rolzad73 starred Principia - https://git.io/fhsRq
<_whitenotifier-a3da> [Principia] vladtcvs edited issue #2383: "No active engines, falling back to RCS" for complicated vessels - https://git.io/Je1ri
<egg|zzz|egg> !wpn whitequark
* galois gives whitequark a neon silicon glaive
<egg|zzz|egg> !wpn UmbralRaptop
* galois gives UmbralRaptop a free electron laser
<_whitenotifier-a3da> [Principia] pleroy opened pull request #2384: Add a new constructor to RigidMotion and use it in the interface - https://git.io/Je1PA
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3976/
<_whitenotifier-a3da> [Principia] pleroy opened issue #2385: Check for the C++ redistributable in the main menu - https://git.io/Je1X3
<_whitenotifier-a3da> [Principia] pleroy labeled issue #2385: Check for the C++ redistributable in the main menu - https://git.io/Je1X3
<_whitenotifier-a3da> [Principia] Failure. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3976/
<UmbralRaptop> that is indeed a weapon
* egg|zzz|egg meows at whitequark
* egg|zzz|egg meows at calling conventions
<egg|zzz|egg> ...
<egg|zzz|egg> __genevacall
<egg|zzz|egg> alternatively
<egg|zzz|egg> __otakall
<_whitenotifier-a3da> [Principia] pleroy synchronize pull request #2384: Add a new constructor to RigidMotion and use it in the interface - https://git.io/Je1PA
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3977/
<_whitenotifier-a3da> [Principia] Success. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3977/
<_whitenotifier-a3da> [Principia] eggrobin reviewed pull request #2384 commit - https://git.io/Je1MU
<_whitenotifier-a3da> [Principia] eggrobin reviewed pull request #2384 commit - https://git.io/Je1MT
<_whitenotifier-a3da> [Principia] eggrobin reviewed pull request #2384 commit - https://git.io/Je1Mk
<_whitenotifier-a3da> [Principia] eggrobin reviewed pull request #2384 commit - https://git.io/Je1ML
<_whitenotifier-a3da> [Principia] pleroy synchronize pull request #2384: Add a new constructor to RigidMotion and use it in the interface - https://git.io/Je1PA
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3978/
<_whitenotifier-a3da> [Principia] Success. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3978/
<egg|zzz|egg> (changing the default calling convention breaks this)
<whitequark> ouch
<whitequark> what in the actual hell is that doing
<_whitenotifier-a3da> [Principia] pleroy synchronize pull request #2384: Add a new constructor to RigidMotion and use it in the interface - https://git.io/Je1PA
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3979/
<egg|zzz|egg> whitequark: suggesting to the linker that this zone_info_source_factory be used if not otherwise defined
<egg|zzz|egg> but weakly, if you actually define zone_info_source_factory, I think this has no effect
<egg|zzz|egg> whitequark: I think I'll have to make zone_info_source_factory a cdecl pointer and the default factory cdecl, because tweaking that monstrosity to make it vectorcall sounds unpleasant
<egg|zzz|egg> and I'm not even sure I can detect the default calling convention with preprocessor macros
<whitequark> rhetorical question
<egg|zzz|egg> I think there are equivalents to that in the GCC world too, I seem to recall stumbling onto libm-related madness like that
<egg|zzz|egg> ah yes the question mentions that
<whitequark> it's much easier with gcc
<whitequark> well, more like, with ELF
<egg|zzz|egg> whitequark: where is the "cries in *" meme from
<whitequark> no idea
<_whitenotifier-a3da> [Principia] Success. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3979/
<egg|zzz|egg> > <egg|zzz|egg> whitequark: I think I'll have to make zone_info_source_factory a cdecl pointer and the default factory cdecl
<egg|zzz|egg> of course that doesn't work
<egg|zzz|egg> because in that monstrous symbol are other cdecls
<egg|zzz|egg> not just that of the pointer
<whitequark> hahaha
<whitequark> ;w;
<whitequark> meanwhile i'm doing arbitrary width arithmetics using C++ templates
<whitequark> it's ... going slightly better than expected
<egg|zzz|egg> oh that sounds fun
<whitequark> it's really goddamn verbose
<egg|zzz|egg> whitequark: here's a C++ crime I want to commit someday https://twitter.com/eggleroy/status/997062110138875905
<kmath> <eggleroy> @stephentyrone @volatile_void Cursed thought: expression-level rounding mode control is probably feasible in C++ on… https://t.co/xLOeVduggW
<whitequark> i could make it less verbose but it'd involve like three levels of foo_traits crap
<whitequark> so i'll just ... keep it verbose
<whitequark> i guess
<egg|zzz|egg> whitequark: I find the foo traits to generally be worth it tbh
<whitequark> well consider like
<whitequark> i could make something like binop_traits and put a functor there that operates per chunk or something
<whitequark> not sure if i'm using "traits" correctly for this
<whitequark> but i'm not sure if it'll actually improve like, anything
<whitequark> and worse
<egg|zzz|egg> yeah, this is fairly readable
<whitequark> for addition and comparison you have to carry (pun intended) over state between chunks
<whitequark> so it'd have to implement fold
<egg|zzz|egg> I thought you meant values-are-types level of madness
<whitequark> and i think i might even need foldl and foldr both
<whitequark> like i *guess* i could extract all the algorithms but eh
<whitequark> i don't know
<whitequark> maybe i will
<egg|zzz|egg> yeah it really depends
<whitequark> right now i dumped all my old code and started over and the level of c++ crimes is super low
<whitequark> i don't even have any SFINAE
<egg|zzz|egg> clearly you need more C++ crimes
<egg|zzz|egg> std::enable_if_t<std::is_criminal_v<Args...>>
<whitequark> lol
<whitequark> oh i'm actually targeting c++11
<whitequark> yosys still uses that
<whitequark> so if i only use c++11 then the generated code runs anywhere yosys does
<whitequark> fortunately it's not like i need anything from c++14 even
egg|cell|egg has joined #kspacademia
<_whitenotifier-a3da> [Principia] eggrobin reviewed pull request #2384 commit - https://git.io/Je1SZ
<_whitenotifier-a3da> [Principia] eggrobin reviewed pull request #2384 commit - https://git.io/Je1Sn
<egg|zzz|egg> so it looks like in C++ it's A for cdecl and Q for vectorcall? Ꙩ_ꙩ
<whitequark> sounds cursed
<whitequark> hm
<whitequark> is there like a constexpr for?
<whitequark> guess not
<egg|cell|egg> Whitequark: what do you want to do?
<egg|cell|egg> There's an if constexpr but that's 17
<egg|cell|egg> There's for or if in constexpr functions in 14
<whitequark> unroll for at compile time
<whitequark> -O3 is probably going to do a good enough job tbh
<whitequark> egg|cell|egg: do you know how to use variadic templates to write a fold?
<whitequark> um
<whitequark> i want to write a `concat(T... args)` that's implemented by doing arg0.concat(arg1.concat(arg2.concat(...)))
<whitequark> could be a different fold too, doesn't matter
<whitequark> oh nvm i can just write it recursively
<egg|zzz|egg> whitequark: re. doing things at compile time for performance, that's not really what things like if constexpr are for (as you say, O3 does the job unless you massively confuse it); if constexpr is semantically different, in that the things in the branch not taken may be illegal
<whitequark> yes, i know
<whitequark> i may not even *want* to unroll the loop
<whitequark> e.g. if i'm summing two 4096 bit values
<whitequark> then probably not
<egg|zzz|egg> yeah
<whitequark> i think verilog allows up to 1 million bit values or something like that
<whitequark> which... actually... would result in some horrifying temporaries
<egg|zzz|egg> s/A/Q/
<whitequark> returning a 16K struct can't possibly be good news
<whitequark> but fortunately yosys chokes on such large values anyway, in violation of the standard, so i don't need to handle them :p
<egg|zzz|egg> but now which As do I need to turn into Q....
<whitequark> can you compile and objdump it instead
<egg|zzz|egg> maybe but that will take ages
<egg|zzz|egg> whitequark: maybe I can find a demangler
<whitequark> MSVC demangler?
<whitequark> #llvm has one
<egg|zzz|egg> yeah
<whitequark> lemme check if it can eat that
<whitequark> er
<whitequark> why did you just link to the or1k clang repo
<egg|zzz|egg> what's or1k
<whitequark> gitlab/or1k/clang
<whitequark> or1k is OpenRISC 1000
<egg|zzz|egg> huh
<egg|zzz|egg> I found it by searching for "Q" "vectorcall"
<egg|zzz|egg> to try to understand the mangled madness
<egg|zzz|egg> demangler.com says msvc
<egg|zzz|egg> it doesn't seem to like these symbols
<whitequark> yeah
<egg|zzz|egg> doesn't remangle though
<whitequark> remangler
<whitequark> heh
<egg|zzz|egg> but at least it understands the symbols
<egg|zzz|egg> ah but it doesn't understand vectorcall symbols
<egg|zzz|egg> there's __FUNCDNAME__ but that's only inside a function
<egg|zzz|egg> and I have a pointer-to-function
<egg|zzz|egg> hmmm
<egg|zzz|egg> there's godbolt
<whitequark> hm, i need to commit parameter pack crimes
<whitequark> okay, i need c++17 fold expressions for that. hrm.
<egg|zzz|egg> whitequark: yeah godbolt works https://gcc.godbolt.org/z/uEDRj4
<egg|zzz|egg> whitequark: parameter pack crimes are nice
<egg|zzz|egg> but yes, C++14 or 17
<whitequark> could you review my code?
<egg|zzz|egg> whitequark: WTF, the mangled symbol is different if you declare something as a class or as a struct
<egg|zzz|egg> whitequark: possibly, but I have very little conteggst
<whitequark> this is an implementation of bit vectors with compile time specified width
<whitequark> i want to slice and concat them, and truncate/sign extend/zero extend them
<egg|zzz|egg> okay
<egg|zzz|egg> (value is a weirdly vague name but I guess it makes sense for whatever you're diong)
<whitequark> later i'm going to add arithmetics as well
<egg|zzz|egg> ominous arithmetic?
<whitequark> arithmetics will have a slightly weird interface because i'm going to lower generics from a completely different interface to it
<egg|zzz|egg> lower?
<whitequark> i'm compiling an IR from a HDL toolchain to C++
<whitequark> so i'm lowering the IR operations to C++ operations
<egg|zzz|egg> aha
<whitequark> translating. simplifying. though i guess this is the opposite of simplification.
<whitequark> still, in a backend you generally do lowering
<egg|zzz|egg> I am unable to read the chunk_traits as anything other than chonk_traits
<whitequark> lol
<whitequark> so the idea is that e.g. i could do foo.slice<31,16>() to get the two most significant octets of foo as a value<16>
<egg|zzz|egg> chunk_traits wants an integer type, probably unsigned, right?
<egg|zzz|egg> if so, I'd static_assert it
<whitequark> done, thanks
<whitequark> indeed a lot of operations would be UB otherwise
<whitequark> i'm mostly worried about zext, shr and shl
<egg|zzz|egg> in terms of correctness or in terms of style
<_whitenotifier-a3da> [Principia] pleroy reviewed pull request #2384 commit - https://git.io/Je1Hc
<whitequark> former
<egg|zzz|egg> I'm not good at bit twiddling so I'd recommend a different reviewer for the correctness aspect (but I am happy to assist in C++ criminality)
<whitequark> oh, hm
<whitequark> okay. do you have any style suggestions?
<whitequark> it seems largely fine but i don't write a lot of c++.
<egg|zzz|egg> not yet but I haven't read through it yet
egg|zzz|egg_ has joined #kspacademia
<whitequark> there's one particularly horrifying aspect i need
<whitequark> i need a version of slice and concat that is an lvalue
<whitequark> returns an lvalue
<egg|zzz|egg_> slightly confused by the interface of the member functions; meow.shr<n>() shifts right, but not by n bits, rather *to* n bits?
<whitequark> yes.
<whitequark> it's like um.
<egg|zzz|egg_> right, for symmetry with extension
<whitequark> yes.
<whitequark> these aren't actually arithmetic operations because arithmetic shifts preserve width.
<whitequark> or logical.
<whitequark> these are basically casts
<egg|zzz|egg_> yeah, they're de-extensions
<whitequark> no, i mean, all members
<egg|zzz|egg_> yeah
<egg|zzz|egg_> what's the difference between copy and zext
<whitequark> copy is an implementation detail of all right-aligned casts
<egg|zzz|egg_> right
<whitequark> i could probably just inline it
<egg|zzz|egg_> copy should probably have the same static_assert
<egg|zzz|egg_> without it, it does UB crimes
<whitequark> ok yeah i should have inlined it, that'd make it obvious
<whitequark> good catch
<whitequark> so in trunc it's n < result.chunks, in sext and zext it's n < chunks
<whitequark> can a const overload and a non-const overload have different return values?
<egg|zzz|egg_> yeah
<whitequark> and the const will be selected preferentially?
<egg|zzz|egg_> the const will be selected if you pass something const
<egg|zzz|egg_> you have that with, say, operator[] on a vector
<whitequark> hm
<whitequark> what if i use a temporary
<whitequark> that would be the non-const one, right
<egg|zzz|egg_> no I think you'll get the const one
<whitequark> alright great
<egg|zzz|egg_> unless you overload on value category as well
<whitequark> and if i try to use the overloaded function on lhs, i'll get the non-const one that returns an rvalue, right
<whitequark> er, an lvalue
<egg|zzz|egg_> if the lhs is non-const
<whitequark> yes
<egg|zzz|egg_> I'm somewhat confused by the masks
<egg|zzz|egg_> they each apply to a specific chunk?
<whitequark> low_mask, high_mask and sign_mask only apply to the last chunk
<egg|zzz|egg_> what do they do
<whitequark> sign_mask is a mask for the sign bit
<whitequark> low_mask is a mask for the sign bit and all less significant ones
<whitequark> high_mask is a mask for all bits more significant than the sign bit, which must always be 0 as an invariant of this data structure
<egg|zzz|egg_> ah
<egg|zzz|egg_> I wonder whether it would be possible to wrap access to the last chunk to enforce that
<egg|zzz|egg_> might be overkill
<egg|zzz|egg_> I'd have a bool sign() const that returns data[chunks - 1] & sign_mask, that seems directly useful
<egg|zzz|egg_> (and you're using data[chunks - 1] & sign_mask in one place already)
<egg|zzz|egg_> (or sign_bit maybe)
<whitequark> done
<egg|zzz|egg_> (or sign_bit_is_negative)
<egg|zzz|egg_> (naming_is_hard)
<whitequark> i think wrapping access is overkill, provided that i deliberately have everything public
<whitequark> yosys doesn't use privacy and this code goes into yosys
<egg|zzz|egg_> concat isn't C++11, right?
<whitequark> it's c++17, yes
<whitequark> i'll probably have to get rid of it
<whitequark> which is ok because all code that uses this API will be generated in the first place
<egg|zzz|egg_> they're good C++ crimes whitequirk
<whitequark> i don't always write c++ / but when i do i generate it from more c++
<egg|zzz|egg_> I do that quite a lot too
<egg|zzz|egg_> (I've shown you the Principia proto-to-C++ and C# interface generator, right?)
<egg|zzz|egg_> (I also do that kind of silliness at work :-p)
<whitequark> i don't think you did, actually
<egg|zzz|egg_> whitequark: it's mostly pleroy's tbh https://github.com/mockingbirdnest/Principia/tree/master/journal
<egg|zzz|egg_> wait no wrong directory
<egg|zzz|egg_> it's a pile of lambdas that produce C# or C++
<whitequark> oic
<egg|zzz|egg_> whitequark: it means that to add an interface function, we add a message in https://github.com/mockingbirdnest/Principia/blob/master/serialization/journal.proto, and the C++ header and C# import both get generated
<egg|zzz|egg_> consistently
<whitequark> yea it makes a lot of sense
<egg|zzz|egg_> because otherwise nothing checks that the declarations match, which is hell
<egg|zzz|egg_> also we use protos to journal, so we can record everything that goes through the interface
<egg|zzz|egg_> and replay the Principia side
<whitequark> i remember that part yes
<whitequark> hm. to handle slices and concats on lhs i should make two view classes, something like value_slice and value_concat
<whitequark> and do read-modify-write operations when they're assigned to
<egg|zzz|egg_> whitequark: yeah slices are nice
<whitequark> question: how do you call a member of the view pointing to the object it is a view of?
<egg|zzz|egg_> hmm
<whitequark> actually, i figured it out, the two specializations can just have different names
<whitequark> for that member
<whitequark> hm. does operator= *have* to return something
<whitequark> i guess it better
<egg|zzz|egg_> no but it would be unidiomatic if it didn't
<whitequark> let's say i have a template<class T, size_t Stop, size_t Start>
<egg|zzz|egg_> [note to self https://gcc.godbolt.org/z/5ggaBX]
<whitequark> i want to change this somehow so everything works like if i had another parameter, size_t Bits = Stop - Start + 1
<whitequark> but i don't want it to be modifiable
<whitequark> so it probably shouldn't be a defaulted parameter
<whitequark> i could add it as a defaulted parameter and also a static_assert but that's gross and would make diagnostics worse
<whitequark> i guess i could just use a static constexpr member
<whitequark> hm. question
<whitequark> ok hm this is very cursed
<whitequark> i'm just going to make it less cursed instead
<egg|zzz|egg_> yeah I don't really see why you need it to be a parameter rather than a constexpr member
<whitequark> turns out i need a constexpr member anyway
<whitequark> because i need to write something like
<whitequark> ok i don't
<whitequark> i wonder if this is going to compile before the sun explodes or not
<whitequark> like
<whitequark> you've seen my API
<whitequark> now imagine something like 100 kLOC of code that uses it
<egg|zzz|egg_> meh
<egg|zzz|egg_> it's really not that mad
<whitequark> i think a lot of the templates could at least be shared
<whitequark> i'm a bit worried about how long it'll spend in inference
<whitequark> and a bit more worried about how long it's gonna inline and optimize out all those loops
<whitequark> well, not inference. how does c++ call it
<whitequark> deduction
<whitequark> "the prolog phase of the compiler"
<whitequark> egg|zzz|egg_: can i write a cast to value<W> where i don't know W?
<whitequark> i know there's *some* operator value<...> but not necessarily what the ... is
<egg|zzz|egg_> whitequark: what do you know about the ...
<whitequark> it's a number
<egg|zzz|egg_> is it the type of something or
<egg|zzz|egg_> uh
<egg|zzz|egg_> whitequark: okay what's the context
<whitequark> ctrl+f XXX
<egg|zzz|egg_> the prolog phase of the compiler <3
<whitequark> i need to cast T to value<something>
<egg|zzz|egg_> whitequark: honestly re. compilation time, I wouldn't worry too much in that instance
<whitequark> so that then i could do shr and trunc on whatever the cast returns
<whitequark> i could cast T to value<T::bits> if there's no other way to write it
<whitequark> so i'm just wondering about it for completeness
<egg|zzz|egg_> what's T here
<whitequark> another slice or a concat
<egg|zzz|egg_> oh huh
<whitequark> slice<value<...>, ...> would be handled in a specialization i think
<whitequark> but basically i'm building a huge tree of slices, concats and values
<egg|zzz|egg_> right your slices have to know what they're slicing
<whitequark> so that i can then assign to it on lhs
<egg|zzz|egg_> that's slightly unusual (string_view and spans and whatever just have a pointer, but your stuff has more structure so you need to know where the ends actually are)
<egg|zzz|egg_> whitequark: this is kind of starting to feel like expression templates
<whitequark> yes. string_view also aren't nested
<whitequark> expression templates?
<galois> [WIKIPEDIA] Expression templates | "Expression templates are a C++ template metaprogramming technique that builds structures representing a computation at compile time, where expressions are evaluated only as needed to produce efficient code for the entire computation. Expression templates thus allow programmers to bypass the normal order..."
<kmath> <eggleroy> @stephentyrone @volatile_void Cursed thought: expression-level rounding mode control is probably feasible in C++ on… https://t.co/xLOeVduggW
<whitequark> yes, i am very much doing boneless expression templates
<whitequark> with just two operations: slice and concat
<whitequark> and honestly it doesn't even need to be very efficient
<whitequark> the reason i'm doing this is that there's a huge project doing a similar thing (verilator), which knows how to parse verilog, synthesize verilog, optimize verilog, and emit optimized C++ code (well, it's mostly C expressions)
<whitequark> and i'm thinking i could offload 70% of what it does to yosys, and the other 30% to clang
<egg|zzz|egg_> yeah that makes sense
<egg|zzz|egg_> so what's the concern with the XXX
<whitequark> so i'm writing a translation layer that converts yosys IR to C++ almost 1:1 (ok, it'll eventually do some optimizations to help alias analysis)
<whitequark> and a C++ library that specializes expressions
<whitequark> oh
<whitequark> well, i was wondering if i could somehow write a cast to value<auto> and have it choose whichever (one) operator value<...>() T has
<egg|zzz|egg_> well, an arbitrary T could have several, so I don't think there really is such a thing
<whitequark> in theory the compiler could complain if it can't decide which one to use
<egg|zzz|egg_> whitequark: you could have all those types have a to_value
<egg|zzz|egg_> or as you said a trait of sorts
<whitequark> right
<whitequark> ok
<whitequark> the other question is: which cast would be appropriate there?
<whitequark> should i just write (value<T::bits>)view ?
<whitequark> i heard c style casts are considered harmful or something
<egg|zzz|egg_> I'd go with static_cast
<whitequark> ok thanks
<whitequark> yea that works
<egg|zzz|egg_> whitequark: I always forget what the relation with C-style casts is
<whitequark> the relation?
<egg|zzz|egg_> the C style casts are overly powerful iirc but I'm not sure exactly in which way
<whitequark> right, they could simultaneously cast types, constness, and um
<whitequark> perform conversions?
<egg|zzz|egg_> whitequark: oh yeah they can remove const
<egg|zzz|egg_> you very rarely want that
<egg|zzz|egg_> and they can reinterpret_cast too, which you basically never want
<egg|zzz|egg_> though that only works through pointers anyway
<whitequark> whaaat, i want reinterpret_cast quite often
<egg|zzz|egg_> (and is not insta-UB only with chars)
<whitequark> hm
<whitequark> wait, i can't reinterpret_cast a float as uint32_t?
<egg|zzz|egg_> nope
<egg|zzz|egg_> UB
<whitequark> ugh
<egg|zzz|egg_> whitequark: bit_cast in the future, memcpy now
* whitequark stabs C++
<whitequark> aaaaaaaaaa
<egg|zzz|egg_> (all compilers now that that memcpy actually does nothing)
<egg|zzz|egg_> reinterpret_cast violates aliasing rules
<whitequark> so you know systemverilog, right
<egg|zzz|egg_> and so would the C-style cast
<whitequark> systemverilog : verilog :: c++ : c
<whitequark> very explicitly
<whitequark> and it's also full of such "attractive nuisance" features
<egg|zzz|egg_> given how much praise you sing of verilog this sounds scary
<whitequark> like verilog has a footgun where it silently infers latches. you *never*, **ever** want latches
<whitequark> so systemverilog adds always_comb and always_ff blocks in which it's supposedly not inferring latches
<whitequark> except i open the spec and it turns out that (a) there is no specification of their behavior. at all. and (b) they're not actually binding
<whitequark> all they do is make the implementation emit a warning if it infers a latch
<egg|zzz|egg_> I recommend writing your own bit_cast with a memcpy in the meantime btw
<whitequark> which it still ACTUALLY HAS TO DO
<egg|zzz|egg_> static_assert equal size and triviality, and memcpy
<whitequark> even though literally no one in the entire history of synthesizable verilog wanted a latch
<_whitenotifier-a3da> [Principia] pleroy synchronize pull request #2384: Add a new constructor to RigidMotion and use it in the interface - https://git.io/Je1PA
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3980/
<egg|zzz|egg_> whitequark: so yeah, reinterpret_cast is the thing you basically never want
<whitequark> ;w;
<egg|zzz|egg_> just like casting C pointers
<egg|zzz|egg_> unless you have pointers to char or unsigned char or std::byte on one side of the cast
<_whitenotifier-a3da> [Principia] eggrobin synchronize pull request #2374: Change the calling convention - https://git.io/Je6eR
<egg|zzz|egg_> I think there's a john regehr post about the aliasing madness
<whitequark> yes i know about strict aliasing
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<whitequark> oh hm
<whitequark> <source>:4:46: error: invalid cast from type 'float' to type 'uint32_t' {aka 'unsigned int'}
<whitequark> 4 | uint32_t x = reinterpret_cast<uint32_t>(f);
<whitequark> i just completely misremembered how reinterpret_cast works then
<egg|zzz|egg_> it casts pointers
<whitequark> right
<whitequark> hm
<egg|zzz|egg_> or refs
<whitequark> ... what the heck is it useful for
<whitequark> oh. references.
<whitequark> can ... can you... cast references?
<egg|zzz|egg_> uint32_t const& x = reinterpret_cast<uint32_t const&>(f); // looking at x is UB
<egg|zzz|egg_> ... what the heck is it useful for << expressing the cursed section of C cast semantics
<whitequark> ugh
<egg|zzz|egg_> C cast semantics were partitioned in the various fancy casts
<whitequark> ok
<whitequark> fine
<egg|zzz|egg_> if it's nothing else, it's a reinterpret
<whitequark> can i cast references with a C-style cast btw?
<whitequark> like... syntactically?
<egg|zzz|egg_> yeah I think so
<egg|zzz|egg_> afk cooking
<_whitenotifier-a3da> [Principia] Success. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3980/
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3981/
<_whitenotifier-a3da> [Principia] Failure. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3981/
<mofh> tl;dr the Romanian gov't fucked up Unicode ON THEIR BANKNOTES
<mofh> also holy fuck that standards fuckup
<mofh> that 20-year chain of standards fuckups
<egg|zzz|egg_> mofh: well everyone does so
<egg|zzz|egg_> s is the messiest one iirc
<egg|zzz|egg_> but the comments in that chain are a bit loaded; the concepts of unification/disunification and what is up to the font and up to the encoding are very very fuzzy as you go back in time
<egg|zzz|egg_> lots of things seem like a good idea at the time
<mofh> I think it's less "seemed like a good idea at the time" and more "this was the only thing possible at the time".
<_whitenotifier-a3da> [Principia] eggrobin labeled pull request #2384: Add a new constructor to RigidMotion and use it in the interface - https://git.io/Je1PA
<egg|zzz|egg_> mofh: same
<egg|zzz|egg_> mofh: lots of things are broken only in hindsight because of things not even conceivable when they are chosen
<egg|zzz|egg_> mofh: e.g. you can't blame the turks for not foreseeing the mess of programmatic capitalization when they chose dotless i
<egg|zzz|egg_> nor the 8-bit encoding for encoding the four different glyphs of i rather than inventing two kinds of "i"ish letters (which would be a different flavour of hell, overly disunified things are also an unholy mess)
<mofh> yeah, like as much as I want to find a time machine to yell at Mustafa Kemal I know he could've never predicted this outcome when he designed that bit of the Turkish alphabet.
<egg|zzz|egg_> mofh: speaking of capitalization you would have to yell at the irish
<mofh> oh?
<_whitenotifier-a3da> [Principia] eggrobin synchronize pull request #2374: Change the calling convention - https://git.io/Je6eR
<_whitenotifier-a3da> [abseil-cpp] eggrobin pushed 1 commit to master [+0/-0/±6] https://git.io/Je151
<_whitenotifier-a3da> [abseil-cpp] eggrobin b2b0c04 - vectorcall
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3982/
<_whitenotifier-a3da> [benchmark] eggrobin pushed 1 commit to master [+0/-0/±4] https://git.io/Je15M
<_whitenotifier-a3da> [benchmark] eggrobin 2079152 - vectorcall
<_whitenotifier-a3da> [gipfeli] eggrobin pushed 1 commit to master [+0/-0/±2] https://git.io/Je15D
<_whitenotifier-a3da> [gipfeli] eggrobin bd986b7 - vectorcall
<_whitenotifier-a3da> [glog] eggrobin pushed 1 commit to master [+0/-0/±6] https://git.io/Je15y
<_whitenotifier-a3da> [glog] eggrobin 3e2dfea - vectorcall
<_whitenotifier-a3da> [googletest] eggrobin pushed 1 commit to master [+0/-0/±9] https://git.io/Je15S
<_whitenotifier-a3da> [googletest] eggrobin f4a29bb - vectorcall
<_whitenotifier-a3da> [Principia] Failure. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3982/
<_whitenotifier-a3da> [protobuf] eggrobin pushed 1 commit to master [+0/-0/±10] https://git.io/Je159
<_whitenotifier-a3da> [protobuf] eggrobin f26f380 - vectorcall
* e_14159_ hands _whitenotifier a megaphone
<egg|zzz|egg_> whitequark: vectorcall changes ^
<whitequark> neat
egg|zzz|egg_ has quit [Remote host closed the connection]
<_whitenotifier-a3da> [Principia] pleroy closed pull request #2384: Add a new constructor to RigidMotion and use it in the interface - https://git.io/Je1PA
<_whitenotifier-a3da> [Principia] pleroy pushed 6 commits to master [+0/-0/±20] https://git.io/Je1dZ
<_whitenotifier-a3da> [Principia] pleroy f7b1290 - Add a new constructor to RigidMotion.
<_whitenotifier-a3da> [Principia] pleroy 7a1d0c5 - Fix compilation error.
<_whitenotifier-a3da> [Principia] pleroy 4474f8f - After egg's review.
<_whitenotifier-a3da> [Principia] ... and 3 more commits.
<_whitenotifier-a3da> [Principia] pleroy opened pull request #2386: Propagate the inertia tensor to the Part - https://git.io/Je1dV
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3983/
<_whitenotifier-a3da> [Principia] Failure. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3983/
egg|zzz|egg_ has joined #kspacademia
<whitequark> egg|zzz|egg: poke
* egg|zzz|egg_ purrs
<egg|zzz|egg_> whitequark: (will have to check on the oven in 3 min, but ask away)
<whitequark> so, my crimes paid off
<egg|zzz|egg_> cxxrtl
<egg|zzz|egg_> right-to-left C++
<whitequark> there was a bug in shl (missed carry in some conditions) but other than that it seems vaguely correct
<whitequark> my question is
<egg|zzz|egg_> whitequark: I would not call them views, because that's not really the term you'd use for an expression template
<egg|zzz|egg_> like
<whitequark> hm
<whitequark> initially i called them just `class slice` but i also want a member function template `slice`
<egg|zzz|egg_> I'd expect a view of a view to be the same type as the view
<whitequark> and i don't know how to disambiguate that
<egg|zzz|egg_> whitequark: slice_expression?
<whitequark> i guess slice_expr would work
<whitequark> changed
<egg|zzz|egg_> I like spelling out words but yeah that works
<whitequark> ok so the thing is i need 4 functions in all of value, slice_expr, concat_expr
<whitequark> slice(), slice()const, concat(), concat()const
<egg|zzz|egg_> argh `.template `, this language is so broken
<whitequark> lol
<whitequark> i want to factor those out somehow
<whitequark> it's not strictly required but would be nice
<egg|zzz|egg_> yeah that seems reasonable
<whitequark> if i just extract them into something like expr_traits then the types don't line up
<whitequark> cuz the type of *this is then expr_traits*
<whitequark> or something
<whitequark> let me try to do this and show you the error
<egg|zzz|egg_> so one pattern that can sometimes help is to have a templatized free function slice (or in a traits class), and then .slice calls that
<whitequark> but... the body is already 1 statement long
<whitequark> if i can't just get rid of the function it makes no sense to do that
<egg|zzz|egg_> yeah
<egg|zzz|egg_> then inheritance might work but that's always hairy
<whitequark> i could make both slice and concat free functions, which *sort of* works but it messes up readability
<whitequark> because slicing is like wire[31:0]
<whitequark> so i want it to become wire.slice<31,0>()
<whitequark> not slice<31,0>(wire)
<egg|zzz|egg_> yeah that definitely makes sense
<egg|zzz|egg_> it's tricky I'll come back in half an hour to an hour, I need to watch my soufflé (food with water vapour as a structural component are kinda time sensitive)
<whitequark> o/
<whitequark> note for myself: https://paste.debian.net/1118759/
<whitequark> egg|zzz|egg_: ok so this works https://paste.debian.net/1118761/
<whitequark> mostly
<whitequark> hm
<whitequark> egg|zzz|egg_: https://paste.debian.net/1118765/
<whitequark> am i using T&& correctly here?
<whitequark> i think i am but not quite sure
<egg|zzz|egg_> whitequark: I am back
<egg|zzz|egg_> at least for a little bit
<egg|zzz|egg_> hm
<egg|zzz|egg_> kinda confused by concat_expr(T &ms_expr, U &&ls_expr) : ms_expr(ms_expr), ls_expr(ls_expr) {}
<whitequark> i'm converting an rvalue reference to an lvalue reference
<whitequark> calling expr_traits::concat should have extended its lifetime until the end of the statement
<whitequark> oh yeah and capturing *_expr is wildly unsafe
<egg|zzz|egg_> hm
<egg|zzz|egg_> okay but why doesn't the other overload do the job
<whitequark> hm
<whitequark> oh it does
<whitequark> i.. am not sure why it didn't before
<whitequark> i changed something else i think
<egg|zzz|egg_> also with respect to concat ( rvalue other), I am wary of that pattern
<whitequark> yes, seems fine
<whitequark> yes, that pattern is a horrifying footgun
<egg|zzz|egg_> yeah rvalues are best kept to the move constructor and assignment
<whitequark> llvm has a StringRef which i think accepts a string&& or something
<whitequark> but there's no way to make this work otherwise, i think
<whitequark> i want to write things like
<whitequark> a.concat(b.slice<7,0>()).slice<19,4>() = (value<24> {0x123456u}).slice<23,8>();
<egg|zzz|egg_> I mean, the llvm devs get a license to do C++ crimes of the highest order in my book, because they have a chance of actually knowing what they are doing
<whitequark> oh StringRef is a constant source of bugs
<whitequark> everyone hates it
<egg|zzz|egg_> lol
<whitequark> exactly the sort of bug you'll expect
<egg|zzz|egg_> preventable use-after-free because your stack variable is no more
<egg|zzz|egg_> ?
<whitequark> correct
<egg|zzz|egg_> (or temporary)
<whitequark> temporary mostly
<whitequark> StringRef s = (some std::string) + ".foo";
<whitequark> boom
<whitequark> or more like
<egg|zzz|egg_> yeah don't take && outside standard patterns (forward, move constructor & assignments) unless several people whom you think they know what they are doing agree
<whitequark> you pass a StringRef constructed from a temporary to some method that takes StringRef
<egg|zzz|egg_> s/they //
<galois> egg|zzz|egg_ meant to say: yeah don't take && outside standard patterns (forward, move constructor & assignments) unless several people whom you think know what they are doing agree
<whitequark> and it then captures it
<whitequark> because of course it captures it to reduce the amount of copies
<egg|zzz|egg_> yeah, getting a lifetime requirement by && is outright evil
<egg|zzz|egg_> getting one by & is already a thing I avoid
<whitequark> solvespace has a rule of no non-const & anywhere
<egg|zzz|egg_> I'm fine with mutable &, but I take anything that wants a lifetime by pointer
<egg|zzz|egg_> whitequark: yeah, that's a google thing too; but so is lifetime by pointer, and I find that constness by pointer sort of makes that rule less powerful
<whitequark> hm
<egg|zzz|egg_> because in google-style code you never know whether "by pointer" means mutates or wants lifetime, and a bunch of stuff is a pointer already because it needs mutation
<egg|zzz|egg_> Principia-style only has "by pointer for lifetime"
<whitequark> solvespace has ... weird lifetimes
<egg|zzz|egg_> mutation by reference is OK, so your mutable reference can't be passed to a thing that also wants lifetime without giving you pause
<whitequark> so the rule is "by-value or by-const-ref if immutable, by-pointer if mutable"
<whitequark> for lifetimes solvespace uses "handles" and avoids storing pointers anywhere
<egg|zzz|egg_> yeah, that's google style wrt mutability
<whitequark> so you only have to make sure you don't capture a reference to something you're about to delete or move
<egg|zzz|egg_> hm
<whitequark> or a pointer
<whitequark> and an invalid handle is an assert (usually) or misbehavior without UB (occasionally)
<egg|zzz|egg_> interesting
<whitequark> it's ... not that great tbh. like the basic idea is ok but handles also encode a notion of hierarchy
<whitequark> and they're fixed size so it gets weird
<whitequark> that's more cad-specific issues though
<whitequark> of course the handles *also* go into savefiles so i can't just change them
<egg|zzz|egg_> aaaaaa
<egg|zzz|egg_> putting the memory model into the serialization is generally cursed
<whitequark> oh, you should have seen the deserialization code
<whitequark> so there are n objects it can deserialize, right?
<whitequark> n types
<whitequark> for each of those, it would create a single instance, and capture pointers to its fields
<whitequark> and fill those fields when encountering the field name in the savefile
<whitequark> but if that wasn't cursed enough, they are also all in a union
<whitequark> SAVEDptr used to be a union
<whitequark> actually i'm pretty sure this is wildly unsound
<_whitenotifier-a3da> [Principia] eggrobin synchronize pull request #2374: Change the calling convention - https://git.io/Je6eR
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3984/
<egg|zzz|egg_> whitequark: re. unions, type punning with unions is technically UB but all known compilers define it as you would expect
<whitequark> yeah but it doesn't work if you stick an std::string into it
<whitequark> which is how i ended up modifying that code
<egg|zzz|egg_> aaaaaaaaaaaaaaa
<whitequark> or it could have been someone else
<kmath> <mczub> alright so we’re going to go out of bounds here to skip this maze, this is called the maze skip https://t.co/HEzRUr4HDl
<whitequark> egg|zzz|egg_: ok weird question but
<whitequark> is there any way to reverse the order of a parameter pack
<egg|zzz|egg_> yes; a good way? let's not get ahead of ourselves
<whitequark> nevermind there is and it's horrifying
<whitequark> i'm just going to live with mixed endian value<> {} initializer
<egg|zzz|egg_> whitequark: you remember you called this bit the prolog phase of C++ compilation right
<egg|zzz|egg_> try to reverse a list in prolog
<whitequark> ahahaha
<whitequark> btw, what do you think about my casts
<whitequark> in expr_traits
<whitequark> is there a less nasty way?
<_whitenotifier-a3da> [Principia] eggrobin synchronize pull request #2374: Change the calling convention - https://git.io/Je6eR
<whitequark> i guess i could probably stuff the casts into .slice()/.concat() themselves
<whitequark> to not define it
<whitequark> er, define the conversion operator on everything that inherits
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<_whitenotifier-a3da> [Principia] Failure. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3984/
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3985/
<_whitenotifier-a3da> [Principia] eggrobin synchronize pull request #2374: Change the calling convention - https://git.io/Je6eR
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<_whitenotifier-a3da> [Principia] Failure. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3985/
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3986/
<egg|zzz|egg_> whitequark: those traits have definitely gone beyond what I would call traits; but they form a reasonably sane base class for expressions; so maybe just expr, or expr_base
<egg|zzz|egg_> whitequark: but I would make the destructor virtual or protected, to avoid users slicing
<whitequark> slicing?
<egg|zzz|egg_> C++ is broken, part n+1 https://en.wikipedia.org/wiki/Object_slicing
<galois> [WIKIPEDIA] Object slicing | "In C++ programming, object slicing occurs when an object of a subclass type is copied to an object of superclass type: the superclass copy will not have any of the member variables defined in the subclass. (These variables have, in effect, been "sliced off".) More subtly, object slicing can also occur..."
<whitequark> asdjfaskdl
<whitequark> ok how does making the destructor virtual help
<egg|zzz|egg_> hmmm
<egg|zzz|egg_> I'm not sure
<whitequark> also i feel like it's not a *huge* issue since this code should all be autogenerated
<egg|zzz|egg_> whitequark: I mean tbh you could also just make this expr_base very hidden (in an internal_do_not_even_think_about_using_this_or_whitequark_will_bite_you namespace) and then nobody will declare pointers to it
<whitequark> oh
<egg|zzz|egg_> (of course this means you need to bite the people who inevitably end up looking into that namespace, which is a lot of work)
<whitequark> lol
<egg|zzz|egg_> (maybe delegate that to your cats)
<whitequark> in some cases i'm fond of "if you broke it, you get to keep all the pieces" approach
<whitequark> in theory the only things users will ever need to do is to convert between e.g. value<64> and uint64_t/int64_t
<whitequark> there should be something like .as<int64_t>()
<whitequark> and maybe value<64>::from(int64_t{1})
<egg|zzz|egg_> yeah that can work
<egg|zzz|egg_> the latter can be tricky
<egg|zzz|egg_> if you want to avoid footguns like T::from(1) being an unexpected type because promotion, you may want a template that says "nope, no weird types" and prevents implicit conversions
<whitequark> yeah i want that
<egg|zzz|egg_> (can even be an explicit constructor, doesn't need to be a factory)
<whitequark> hm. can i use SFINAE to choose between template function implementations?
<_whitenotifier-a3da> [Principia] Failure. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3986/
<whitequark> i want a zcast() which calls either zext() or trunc()
<whitequark> could obviously do with if constexpr but what if i still want c++11
<egg|zzz|egg_> hmmmm
<whitequark> ./cxxrtl.hh:114:18: error: function template partial specialization is not allowed
<whitequark> clang doesn't like what i wrote
<whitequark> which is value<NewBits> zcast<NewBits, std::enable_if_t<(NewBits < Bits)>>() const {
<egg|zzz|egg_> yeah that's not a thing
<egg|zzz|egg_> whitequark: maybe tempalte<blah> using zcast_function = std::conditional_t<(some comparison>, std::integral_constant<decltype(&value::zext), &value::zext>>, std::integral_constant<decltype(&value::zcast), &value::zcast>>
<whitequark> ouch
<egg|zzz|egg_> (basically a helper type; might be more readable to have a zcast_trait with 2 specializations)
<egg|zzz|egg_> s/zcast::/trunc/g
<egg|zzz|egg_> s/zcast::/trunc::/g even
<egg|zzz|egg_> wait no
<egg|zzz|egg_> s/::zcast/::trunc/g
<galois> egg|zzz|egg_ meant to say: whitequark: maybe tempalte<blah> using zcast_function = std::conditional_t<(some comparison>, std::integral_constant<decltype(&value::zext), &value::zext>>, std::integral_constant<decltype(&value::trunc), &value::trunc>>
<egg|zzz|egg_> whee
<whitequark> ./cxxrtl.hh:111:39: error: reference to overloaded function could not be resolved; did you mean to call it? std::integral_constant<decltype(&value<Bits>::zext), &value::zext>,
<whitequark> hm
<egg|zzz|egg_> oh right it's overloaded
<egg|zzz|egg_> aaa
<egg|zzz|egg_> I should pack my luggage
<egg|zzz|egg_> afk a bit
<whitequark> tbh i don't really need those overloads
<whitequark> i can just generate the right cast
<whitequark> oh. hm.
<whitequark> not quite ok
<_whitenotifier-a3da> [Principia] eggrobin synchronize pull request #2374: Change the calling convention - https://git.io/Je6eR
<_whitenotifier-a3da> [Principia] Pending. Build queued… - 
<_whitenotifier-a3da> [Principia] Pending. Building… - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3987/
<egg|zzz|egg_> whitequark: i'm back
<egg|zzz|egg_> whitequark: prolog is good tho
<_whitenotifier-a3da> [Principia] Success. Build finished. - http://casanova.westeurope.cloudapp.azure.com:8080/job/Principia/3987/
<egg|zzz|egg_> whee it builds
<egg|zzz|egg_> i should zzz
<UmbralRaptop> !8 should egg zzz?
<galois> UmbralRaptop: no
<egg|zzz|egg_> but train tomorrow
<UmbralRaptop> sleep on the train?
<egg|zzz|egg_> but principia