Hacker Newsnew | past | comments | ask | show | jobs | submit | Conscat's commentslogin

I work at Nvidia, and my team is using Slang for all of our (numerous and non-trivial) kernels because its automatic differentiation type system is so nice.


> BJP ... is staunchly supporting Upper caste ( Brahmins).

I'm curious what you mean by this. I've heard a wide range of opinions on BJP from NRIs, but that's one position I haven't been told before. My understanding was that BJP supports caste and village inclusivity in universities and professional fields to such an extent that some people from tier 1 cities even feel left out.


Do you read the Clang git commit log every day? C++ improves in many ways faster than any other language ecosystem.


I think he was referring to the language specification, not a specific compiler.


But that is also wrong, as per the article C++ 26 got some improvements in a hardening profile.


I see that C++26 has some incredibly obscure changes in the behavior of certain program constructs, but this does not mean that these changes are improvements.

Just reviewing the actual hardening of the standard library, it looks like in C++26 an implementation may be considered hardened in which case if certain preconditions don't hold then a contract violation triggers an assertion which in turn triggers a contract violation handler which may or may not result in a predictable outcome depending on one of 4 possible "evaluation semantics".

Oh and get this... if two different translation units have different evaluation semantics, a situation known as "mixed-mode" then you're shit out of luck with respect to any safety guarantees as per this document [1] which says that mixed-mode applications shall choose arbitrarily among the set of evaluation semantics, and as it turns out the standard library treats one of the evaluation semantics (observe) as undefined behavior. So unless you can get all third party dependencies to all use the same evaluation semantic, then you have no way to ensure that your application is actually hardened.

So is C++26 adding changes? Yes it's adding changes. Are these changes actual improvements? It's way to early to tell but I do know one thing... it's not at all uncommon that C++ introduces new features that substitute one set of problems for a new set of problems. There's literally a 300 page book that goes over 20 distinct forms to initialize an object [2], many of these forms exist to plug in problems introduced by previous forms of initialization! For all we know the same thing might be happening here, where the classical "naive" undefined behavior is being alleviated but in the process C++ is introducing an entire new class of incredibly difficult to diagnose issues. And lest you think I'm just spreading FUD, consider this quote from a paper titled "C++26 Contracts are not a good fit for standard library hardening" [3] submitted to the C++ committee regarding this upcoming change arguing that it risks giving nothing more than the illusion of safety:

>This can result in violations of hardened preconditions being undefined behaviour, rather than guaranteed to be diagnosed, which defeats the purpose of using a hardened implementation.

[1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p29...

[2] https://www.amazon.ca/dp/B0BW38DDBK?language=en_US&linkCode=...

[3] https://isocpp.org/files/papers/P3878R0.html


I believe there were some changes in the November C++ committee meeting that (ostensibly) alleviates the some of the contracts/hardening issues. In particular:

- P3878 [0] was adopted, so the standard now forbids "observe" semantics for hardened precondition violations. To be fair, the paper doesn't explicitly say how this change interacts with mixed mode contract semantics, and I'm not familiar enough with what's going on to fill in the gaps myself.

- It appears there is interest in adopting one of the changes proposed in D3911 [1], which introduces a way to mark contracts non-ignorable (example syntax is `pre!()` for non-ignorable vs. the current `pre()` for ignorable). A more concrete proposal will be discussed in the winter meeting, so this particular bit isn't set in stone yet.

[0]: https://isocpp.org/files/papers/P3878R1.html

[1]: https://isocpp.org/files/papers/D3911R0.html


Mixed mode is about the same function compiled with different evaluation semantics in different TUs, and it is legit. The only case they are wondering about is how deal with inlined functions and they suggest ABI extensions to support it during the link-time. None of what you said is an issue.

> The possibility to have a have a well-formed program in which the same function was compiled with different evaluation semantics in different translation units (colloquially called “mixed mode”) raises the question of which evaluation semantic will apply when that function is inline but is not actually inlined by the compiler and is then invoked. The answer is simply that we will get one of the evaluation semantics with which we compiled.

> For use cases where users require strong guarantees about the evaluation semantics that will apply to inline functions, compiler vendors can add the appropriate information about the evaluation semantic as an ABI extension so that link-time scripts can select a preferred inline definition of the function based on the configuration of those definitions.


Not sure what you mean by the term "legit".

The entirety of the STL is inlined so it's always compiled in every single translation unit, including the translation units of third party dependencies.

Also it's not me saying, it's literally the authors of the MSVC standard library and the GCC standard library pointing out these issues [1]:

[1] https://isocpp.org/files/papers/P3878R0.html


Legit as in allowed and not an issue as you're trying to convey, ok? I read the paper if that wasn't already obvious from my comment. What you said is factually incorrect.


Not sure I understand what point you're trying to dispute. It's not obvious at all that you read either my post or the paper I posted authored by the main contributors to MSVC and GCC about the issues mixed-mode applications present to the implementation of the standard library given that you haven't presented any defense of your position that addresses these issue. You seem to think that just declaring something "legit" and retorting "you are incorrect" is a sufficient justification.

If this is the extent of your understanding it's a fairly good indication you do not have sufficient background on this topic and may be expressing a very strong opinion out of ignorance of this topic. It's not at all uncommon that those with the most superficial understanding of a subject express the strongest views of said topic [1].

Doing a cursory review of some of your recent posts, it looks like this is a common habit of yours.

[1] https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect


I have literally copy-pasted the fragments from the paper you're referring to which invalidate your points. How is that not obvious? Did you read the paper yourself or you're just holding strong opinions yourself, as you usually do whenever there is something to backlash against C++? I'm glad you're familiar with the Dunning-Kruger effect, this means there is some hope for you.


The implementations of hardening in libc++ and libstdc++ are available now and are straightforward to use.

https://libcxx.llvm.org/Hardening.html

https://gcc.gnu.org/wiki/LibstdcxxDebugMode (was already available for longer, the official hardening might take this over or do something else)


Violation of preconditions is always undefined behavior, this isn't new.


The problem is that violation of preconditions being UB in a hardened implementation sort of defeats the purpose of using the hardened implementation in the first place!

This was acknowledge as a bug [0] and fixed in the draft C++26 standard pretty recently.

[0]: https://isocpp.org/files/papers/P3878R1.html


>A hardened implementation that uses 'observe' is not hardened

The proposal simply included a provision to turn off hardening, nothing else. Traditionally these checks were under #ifndef NDEBUG


> The proposal simply included a provision to turn off hardening, nothing else.

(Guessing "the proposal" refers to the hardening proposal?)

I don't think that is correct since the authors of the hardening proposal agreed that allowing UB for hardened precondition violations was a mistake and that P3878 is a bug fix to their proposal. Presumably the intended way to turn off handling would be to just... not enable the hardened implementation in the first place?


Using #ifndef NDEBUG in templates is one of the leading causes of one-definition rule violations.

At least traditionally it was common to not mix debug builds with optimized builds between dependencies, but now with contracts introducing yet another set of orthogonal configuration it will be that much harder to ensure that all dependencies make use of the same evaluation semantic.


If I couldn't give Emacs incredibly specialized behavior, I wouldn't even use it.


This article elaborates how it works.


Unhelpful response. This cuongle.dev article does not answer nextaccountic's question, and neither do the webkit.org articles that describe the parking lot concept but not this Rust implementation. The correct answer appears to be that it's impossible: `parking_lot::RawMutex` has private storage that owns the entire byte and does not provide any accessor for the unused six bits.

https://docs.rs/parking_lot/0.12.5/parking_lot/struct.RawMut...

(unless there's somewhere else in the crate that provides an accessor for this but that'd be a weird interface)

(or you just use transmute to "know" that it's one byte and which bits within the byte it actually cares about, but really don't do that)

(slightly more realistically, you could probably use the `parking_lot_core::park` portion of the implementation and build your own equivalent of `parking_lot::RawMutex` on top of it)

(or you send the `parking_lot` folks a PR to extend `parking_lot::RawMutex` with interface you want; it is open source after all)


> and neither do the webkit.org articles that describe the parking lot concept but not this Rust implementation

The WebKit post explicitly talks about how you just need two bits to describe the lock state.

> The correct answer appears to be that it's impossible: `parking_lot::RawMutex` has private storage that owns the entire byte and does not provide any accessor for the unused six bits.

Not impossible. One way to do this is to just use parking_lot directly.

In WebKit there’s a template mixin that lets you steal two bits for locking however you like. JavaScriptCore uses this to steal two bits from the indexing type byte (if I remember right)


> The WebKit post explicitly talks about how you just need two bits to describe the lock state.

It describes the algorithm but not how a caller of the Rust `parking_lot` crate could take advantage of this.

> Not impossible. One way to do this is to just use parking_lot directly.

By "just use parking_lot directly", I think you're talking about reimplementing the parking lot algorithm or using the C++ `WTF::ParkingLot` implementation? But not actually using the existing Rust crate called `parking_lot` described in the cuongle.dev article? That's confusingly put, and nextaccountic's question is certainly Rust-specific and likely expecting an answer relating to this particular crate. At the least, "does this use unsafe" would certainly be true with an implementation from scratch or when using FFI into C++.

I hear that this algorithm and the C++ implementation are your invention, and all due respect for that. I'm also hearing that you are not familiar with this Rust implementation. It does not offer the main benefit you're describing. `parking_lot::RawMutex` is a one-byte type; that six bits within it are unused is true but something callers can not take advantage of. Worse, `parking_lot::Mutex<InnerFoo>` in practice is often a full word larger than `InnerFoo` due to alignment padding. As such, there's little benefit over a simpler futex-based approach.


> It describes the algorithm but not how a caller of the Rust `parking_lot` crate could take advantage of this.

Read the WebKit post.

> By "just use parking_lot directly", I think you're talking about reimplementing the parking lot algorithm or using the C++ `WTF::ParkingLot` implementation? But not actually using the existing Rust crate called `parking_lot` described in the cuongle.dev article?

See https://docs.rs/parking_lot_core/latest/parking_lot_core/

That's my ParkingLot API. You can use it to implement many kinds of locks, including:

- Efficient ones that use a tristate, like the glibc lowlevellock, or what I call the Cascade lock. So, this doesn't even need two bits.

- The lock algorithm I prefer, which uses two bits.

- Lots of other algorithms. You can do very efficient condition variables, rwlocks, counting locks, etc.

You can do a lot of useful algorithms with fewer than 8 bits. You don't have to use the C++ ParkingLot. You don't have to implement parking_lot.

What you do have to do is RTFM


> Read the WebKit post.

Clearly I have already.

> See https://docs.rs/parking_lot_core/latest/parking_lot_core/ ... That's my ParkingLot API.

"just use parking_lot directly" is a weird way to say "use the `parking_lot_core` crate instead of the `parking_lot` crate".

...and note that I mentioned this in my earlier comment: (slightly more realistically, you could probably use the `parking_lot_core::park` portion of the implementation and build your own equivalent of `parking_lot::RawMutex` on top of it)

I'm not trying to be disagreeable here, but really you could save a lot of trouble if you were a bit more careful in your communication.


The two bit lock was specifically refering to the C++ WTF::ParkingLot (and the comment mentioning it explicitly said that). nextaccountic is confused.


No. nextaccountic's comment and the cuongle.dev article are both talking about Rust. The Rust `parking_lot` implementation only uses two bits within a byte, but it doesn't provide a way for anything else to use the remaining six.

pizlonator's comments mention both the (C++) WTF::ParkingLot and the Rust `parking_lot`, and they don't answer nextaccountic's question about the latter.

> nextaccountic is confused.

nextaccountic asked how this idea could be applied to this Rust implementation. That's a perfectly reasonable question. pizlonator didn't know the anwer. That's perfectly reasonable too. Conscat suggested the article would be helpful; that was wrong.


nextaccountic replied to this original comment: https://news.ycombinator.com/item?id=46035698

Yes, nextaccountic's reply is confused about Rust vs C++ implementations. But the original mention was not talking about Rust.


I'm on HackerNews because I can't do my job right now.


I'm on HN because I don't want to do my job right now.


I work in the wrong time zone. Good night.


I know we must have some terminally online fediverse users here. One of them must have an idea what he is alluding to.


That looks exactly like the photos on a Spirit Halloween costume.


I'm in tears. Clicked to check out Dracula and sure enough it's a spot on spirit halloween dollar tree Dracula.


The Sherlock Holmes is heavily influenced by Cucumber Patch.


People pay consulting firms good money to be told their ideal customer so plainly!


"move" means to pass into an r-value reference function parameter, for instance a move constructor, move assignment operator, or forwarding reference.


It's hard to say what "that hard" should be considered, but the book's first half involves Java reflection, which isn't obvious code to port to different languages in my opinion.


> the book's first half involves Java reflection

Does it? I know it uses metaprogramming (a Java program that outputs another Java program), but that’s probably easier in other languages than in Java. In my Python implementation I was able to significantly simplify that part of the code by using `eval`.


Yeah I don't recall reflection either.

I do remember him using the visitor pattern to implement part of the parser I think. I thought that was kind of an odd choice, especially since it seemed like he was really just trying to avoid Java boilerplate.

Regardless, the book is incredible, and the choice of Java to start with makes sense. Its probably going to be the most universally approachable for everyone, even if they aren't super familiar. C can be pretty overwhelming if you aren't familiar it.


> I do remember him using the visitor pattern to implement part of the parser I think. I thought that was kind of an odd choice, especially since it seemed like he was really just trying to avoid Java boilerplate.

It's used to allow writing a "resolver" and an "interpreter" that both know how to handle every type of node in the AST. It's almost a functional approach, and I actually think it might increase boilerplate because Java is more designed around the object-oriented approach of adding `resolve` and `interpret` methods directly to each node type.

The two approaches result in very different code organisation, though - maybe the visitor approach was easier to explain in prose.


It's been a while since I read it, but I remember him saying something about the more natural (my word not his) approach being a single data structure that you would pass through both components, but he didn't want to do that because Java doesnt really encourage that kind of design, and you have a bunch of boilerplate for each class. It just struck me as an odd choice since the book was more about compiler/interpreter fundamentals, and I feel like the visitor pattern is a bit in the weeds in terms of OOP design.

I wonder if he wrote today if he would have used a Record and done the more straightforward implementation.


I went through the Crafting Interpreters book with modern Java. I posted this on reddit, but I basically used records and sealed interfaces. With modern Java there's no need for visitor pattern.

    private void execute(Stmt statement) {
        switch (statement) {
            case Stmt.Expression expression -> evaluate(expression.expr());
            case Stmt.Block block -> executeBlock(block.statements(),
               new Environment(environment));
            ...

    public sealed interface Expr permits
        Expr.Assign,
        Expr.Binary,
        Expr.Call,
        Expr.Function,
        .... more exprs here


Interesting. Almost all my actual experience writing Java is in Java 8, so I'm not super familiar with the modern stuff (other then a few things like Records). I'll have to take a look.

Most of the people I know who write Java would have an aneurysm at seeing a switch statement.

To be clear, that's a critique of the Java mindset, not your code. Lol


It's been a few years now, but there's no real reason to port the Java code directly – you can just read what it's trying to do, and implement that using your language's idioms. I don't remember anything as complex as trying to port reflection.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: