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

BTQH?

Maybe a typo for To Be Quite Honest?

What the deuce is an "RPA"?

Its an acronym for Robotic Process Automation. It usually means triggering mouse clicks and key stokes to perform tasks

It's a script that simulates clicks/keystrokes on Desktop/Web

The massive AI generated image header is more than a little bit ironic

The “Question? Answer.” format seems way overused, too. I don’t usually comment on “LLMiness” of blog posts, but here it seems to somewhat devalue the point the author is trying to make.

It is, indeed, heartbreaking to learn that the one person in a giant corporation that cared about your problem enough to pull some strings and fix it gets laid off. But if you truly care about them, why don’t you try and write about it yourself, in your own voice?


The obviously ai generated dramatic prose. The entire site has the veneer of AI generation as well. The gradient background, the glowing header text, the monospaced fonts, the dots next to the footer subnav items that serve no purpose. If i were writing a blog today i would take comfort knowing it has never been easier to stand out by simply being yourself.

It's the best there is.

> The interesting thing here is the Undefined Behavior (UB), well... actually two UBs, thanks to which there are three possible correct answers: 11, 12 and 13.

No, if you invoke undefined behavior any result at all is possible.


Hey! Author here :)

So let me start by saying that that blog post was written was 15 years ago and I don't even remember the details of it and what I've written there. But, I have a hot-take on this topic you've touched on!

From a programmer perspective, you are absolutely right. The behaviour is undefined, end of discussion. A programmer should never rely on what they observe as the effective behaviour of an UB. A programmer must avoid creating situations in code that could result in the execution flow venturing into the areas of UB. And - per C and C++ standards - results of UB can be anything (insert the old joke about UB formatting one's disk being a formally correct behaviour).

However, I'm a security researcher, and from the security point of view - especially on the offensive side - we need to know and understand the effective behaviours of UBs. This is because basically all "low-level" vulnerabilities in C/C++ are formally effects of UBs. As such, for the security crowd, it still makes sense to investigate, understand, and discuss the actual observed effects of UBs, especially why a compiler does this, what are the real-world actual variants of generated code (if any) for a given UB for this and other compilers, how can this be abused and exploited, and so on.

My point being - there are two sides to this coin.


Agreed.

As a programmer, the solution to "int a = 5; a = a++ + ++a;" is to decide what you result you wanted, and write code that will produce that result, and probably to pass options to the compiler that tell it to detect this kind of problem and print a warning. (On my system, the result happens to be 12; if that's what I want, I'll write "int a = 12;").

But if you have an existing program that includes that code, it can be useful to look into the actual behavior (for all the compilers that might be used to compile the code, with all possible options, on all possible target systems). Fixing the code should be part of that process, but you might still have running systems with the old bad code, and you need to understand the risks.

But producing some numeric result is not the only possible behavior, even in real life. Compilers can assume that the code being compiled does not have undefined behavior, and generate code based on that assumption. The results can be surprising.

As for formatting your disk, that's not just a theoretical risk. If a program has enough privileges that it can format your disk deliberately, it's possible that it could do so accidentally due to undefined behavior (for example, if a function pointer is corrupted).


> My point being - there are two sides to this coin.

No, you're simply wrong. UB means that anything can happen. And from a security perspective, that is vital to understand.

The only proper response to this code (or similar UB due to ambiguous sequence points) if found in production is to rewrite it and fire or reeducate the author.

Sorry, but some people just aren't competent.


Actually, I do think I'm right ;)

There are two layers two this. On the formal, C and C++ standard lawyering layer, UB can have any result. I of course agree with this as per my previous comment.

However, the compilers are an actual implementation, and actual implementations do things in deterministic ways (even if randomness is involved, realistically it is limited to a certain set of outcomes). As such, in case of UBs it's not "anything can happen" - there is actually a limited set of things that can happen.

And I do believe you've missed the "especially on the offensive side" part of my comment. What you are saying about "if found in production is to rewrite it and fire or reeducate the author" is the defensive security perspective, not the offensive security one. From the offensive security perspective you aren't there to fix the code - you are there to exploit it and hack into the system / leak info / raise your privileges.


I feel we need another category - unspecified behavior. I think everyone would agree the compiler should putout ONE of those answers and that nasal demons would be out of spec.

The problem is that it’s not specified which should be picked, but all pick something.


I agree what you say seems reasonable at a glance. But (IIUC) the issue is that for optimization we want the compiler to assume that UB doesn't happen in order to constrain the possible code paths. So if it goes some distance down a possible execution branch and discovers UB it can trim the subtree. At that point "anything can happen" becomes an (approximate) reality.

The obvious counterpoint in this particular instance is that there's no good reason not to make such an awful expression a compile time error.

I also personally think that evaluation order should be strictly defined. I'm unclear if the current arrangement ever offers noticable benefits but it is abundantly clear that it makes the language more difficult to reason about.


As I understand it UB was not really intended to be for optimisation. It was so that C could compile on wildly different architectures that existed at the time.

Today we don't have nearly the variety of architectures, so they in theory C doesn't need nearly as much UB (like more modern languages).

Although there is one modern case where C's "anything goes" attitude has actually helped: CHERI works pretty well with C/C++ even though pointers are double the size they normally are, because doing so many things with pointers is UB (I assume because of segmented memory). CHERI is a slightly awkward target for Rust because Rust makes more assumptions about pointers - specifically that pointers and addresses are the same size.


Which is a form of optimization- if you don’t require something that may be incredibly difficult on a given CPU it makes portability easier.

The reality is these are all edge conditions rarely encountered.


is the fact that CHERI works better with C/C++ because of C/C++'s "anything goes" attitude, or simply that any hardware design that didn't support C/C++ well was discarded?


The C and C++ standards include "Implementation defined behavior", which means that a conforming implementation can do whatever it wants, as long as it specifically documents and sticks to that behavior.

This doesn't really help portability all that much.


That's a different category. Standard defines and uses all 3 "undefined", "implementation defined" and "unspecified" behavior. The difference between last two is that compiler isn't required to document exact behavior. Unlike UB triggering it doesn't automatically summon nasal demons and range of possible behaviors is usually described by standard.


That already exists, and it is in fact called unspecified behavior. Order of function argument evaluation is unspecified, for instance.


Pyinfra is what ansible should have been. It's straight python rather than a janky mix of yaml, templates, and bolted-on control flow primitives.


There is this: https://github.com/seantis/suitable

But the main guy who developed it at that company left, so no idea on its longevity.


Oh hey that's me! Yeah I don't think you would want to use this, it was never used outside some smaller automation utils afaik.


Yeah I guess; I'm generally not a fan of solving a problem by adding another layer of shit on top.


"It's possible to write <lang-X> in <lang-Y>" is a common trope, but "It's possible to write <lang-X> in Rust" is painful and borderline impossible in my experience. I don't mean this as a defense of rust, I just think it's why the learning curve is so harsh.


Can you say more about the system? A lifetime ago I was really excited about gambit (and bigloo) but I never had the chance to work with them beyond messing around here and there after work.


Deadly Rooms of Death is criminally underrated and generally unknown. Journey to Rooted Hold is personally my DRoD of choice.


It works both ways: "Yeah, let me eat 100kg of beef per day instead of 500g of broccoli to get my Vitamin C."

But anyway, legumes are much more efficient source of protein than beef. I don't understand why you decided to compare against broccoli.


Maybe we should eat both then.


Sorry, let me eat 1.8kg of lentils instead. The point I was making is that there is a need for both.


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

Search: