Live data from Hacker News

Undefined Behavior in C and C++ (2024)

russellw.github.io

61–70 of 234 posts

Re: Undefined Behavior in C and C++ (2024)

#61

I don’t buy the “it’s because of optimization argument”. And I especially don’t buy that UB is there for register allocation. First of all, that argument only explains UB of OOB memory accesses at best. Second, you could define the meaning of OOB by just saying “pointers are integers” and then further state that nonescaping locals don’t get addresses. Many ways you could specify that, if you cared badly enough. My fa…

> Second, you could define the meaning of OOB by just saying “pointers are integers"

This means losing a lot of optimisations, so in fact when you say you "don't buy" this argument you only mean that you don't care about optimisation. Which is fine, but this does mean the "improved" C isn't very useful in a lot of applications, might as well choose Java.

Re: Undefined Behavior in C and C++ (2024)

#62
post #28
post #7

One has to add that from the 218 UB in the ISO C23, 87 are in the core language. From those we already removed 26 and are in progress of removing many others. You can find my latest update here (since then there was also some progress): https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3529.pdf

And yet, I see P1434R0 seemingly trying to introduce new undefined behavior, around integer-to-pointer conversions, where previously you had reasonably sensible implementation defined behavior (the conversions “are intended to be consistent with the addressing structure of the execution environment" ). https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p14...

Pointer provenance already existed before, but the standards were contradictory and incomplete. This is an effort to more rigorously nail down the semantics.

i.e., the UB already existed, but it was not explicit had to be inferred from the whole text and the boundaries were fuzzy. Remember that anything not explicitly defined by the standard, is implicitly undefined.

Also remember, just because you can legally construct a pointer it doesn't mean it is safe to dereference.

Re: Undefined Behavior in C and C++ (2024)

#63
post #56

Earlier quoted context omitted.

"Mit dem Angriff Steiner's wird das alles in Ordnung kommen" ;) As shitty as C++ is from today's PoV, the entire gaming industry switched over within around 3 years towards the end of the 90s. 6..7 years is a long time, and a single engine (especially when it's more or less just a runtime without editor and robust asset pipeline) won't change the bigger picture that Rust is a pretty poor choice for gamedev.

> As shitty as C++ is from today's PoV, the entire gaming industry switched over within around 3 years towards the end of the 90s. Did they? What's your evidence? Are you including consoles? Btw, the alternatives in the 1990s were worse than they are now, so the bar to clear for eg C or C++ were lower.

I was there Gandalf... ;) Console SDKs offering C or C++ APIs doesn't really matter, because you can call C APIs from C++ just fine. So the language choice was a team and engine developer decision, not a platform owner decision (as it should be).

From what I've seen, around the late mid-90's, C++ usage was still rare, right before 2000 it was already common and most middleware didn't even offer C APIs anymore.

Of course a couple of years later Unity arrived and made the gamedev language choice more complicated again.

Re: Undefined Behavior in C and C++ (2024)

#64
post #56

Earlier quoted context omitted.

> As shitty as C++ is from today's PoV, the entire gaming industry switched over within around 3 years towards the end of the 90s. Did they? What's your evidence? Are you including consoles? Btw, the alternatives in the 1990s were worse than they are now, so the bar to clear for eg C or C++ were lower.

I was there Gandalf... ;) Console SDKs offering C or C++ APIs doesn't really matter, because you can call C APIs from C++ just fine. So the language choice was a team and engine developer decision, not a platform owner decision (as it should be). From what I've seen, around the late mid-90's, C++ usage was still rare, right before 2000 it was already common and most middleware didn't even offer C APIs anymore. Of cou…

> I was there Gandalf... ;)

You were at most in one place. My question was rather, which corners of the industry are you counting?

However you are right that one of the killer features of C++ was that it provided a pretty simple upgrade path from C to (bad) C++.

It's not just API calls. You can call C APIs from most languages just fine.

Re: Undefined Behavior in C and C++ (2024)

#65
post #8

Earlier quoted context omitted.

Advantages of C are short compilation time, portability, long-term stability, widely available expertise and training materials, less complexity. IMHO you can today deal with UB just fine in C if you want to by following best practices, and the reasons given when those are not followed would also rule out use of most other safer languages.

This is a pet peeve, so forgive me: C is not portable in practice. Almost every C program and library that does anything interesting has to be manually ported to every platform. C is portable in the least interesting way, namely that compilers exist for all architectures. But that's where it stops.

Compilers existing is essential and not trivial (and also usually then what other languages build on). The conformance model of C also allows you to write programs that are portable without change to different platforms. This is possible, my software runs on 20 different architectures without change. That one can then also adopt it to make use of specific features of different platforms is quite natural in my opinion.

Re: Undefined Behavior in C and C++ (2024)

#66
post #54

Earlier quoted context omitted.

It won't be a "random garbage value" but is instead a value the compiler chose. In effect if you don't opt out your value will always be initialized but not to a useful value you chose. You can think of this as similar to the (current, defanged and deprecated as well as unsafe) Rust std::mem::uninitialized() There were earlier attempts to make this value zero, or rather, as many 0x00 bytes as needed, because on most…

What are these worse bugs?

The classic thing is, we're granting user credentials - maybe we're a login proces, or a remote execution helper - and we're on Unix. In some corner case we forget to fill out the user ID. So it's "random noise". Maybe in the executable distributed to your users it was 0x4C6F6769 because the word "Login" was in that memory in some other code and we never initialized it so...

Bad guys find the corner case and they can now authenticate as user 0x4C6F6769 which doesn't exist and so that's useless. But - when we upgrade to C++ 26 with the hypothetical zero "fix" now they're root instead!

Re: Undefined Behavior in C and C++ (2024)

#67
post #8

Earlier quoted context omitted.

Advantages of C are short compilation time, portability, long-term stability, widely available expertise and training materials, less complexity. IMHO you can today deal with UB just fine in C if you want to by following best practices, and the reasons given when those are not followed would also rule out use of most other safer languages.

> short compilation time > IMHO you can today deal with UB just fine in C if you want to by following best practices In the other words, short compilation time has been traded off with wetware brainwashing... well, adjustment time, which makes the supposed advantage much less desirable. It is still an advantage, I reckon though.

I do not understand what you are tying to say, but it seems to be some hostile rambling.

Re: Undefined Behavior in C and C++ (2024)

#68
post #28

Earlier quoted context omitted.

And yet, I see P1434R0 seemingly trying to introduce new undefined behavior, around integer-to-pointer conversions, where previously you had reasonably sensible implementation defined behavior (the conversions “are intended to be consistent with the addressing structure of the execution environment" ). https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p14...

Pointer provenance already existed before, but the standards were contradictory and incomplete. This is an effort to more rigorously nail down the semantics. i.e., the UB already existed, but it was not explicit had to be inferred from the whole text and the boundaries were fuzzy. Remember that anything not explicitly defined by the standard, is implicitly undefined. Also remember, just because you can legally constr…

Pointer provenance was certainly not here in the 80s. That's a more modern creation seeking to extract better performance from some applications at a cost of making others broken/unimplementable.

It's not something that exists in the hardware. It's also not a good idea, though trying to steer people away from it proved beyond my politics.

Re: Undefined Behavior in C and C++ (2024)

#69

Undefined behavior only means that ISO C doesn't give requirements, not that nobody gives requirements. Many useful extensions are instances where undefined behavior is documented by an implementation. Including a header that is not in the program, and not in ISO C, is undefined behavior. So is calling a function that is not in ISO C and not in the program. (If the function is not anywhere, the program won't link. Bu…

> Including a header that is not in the program, and not in ISO C, is undefined behavior.

What is this supposed to mean? I can't think of any interpretation that makes sense.

I think ISO C defines the executable program to be something like the compiled translation units linked together. But header files do not have to have any particular correspondence to translation units. For example, a header might declare functions whose definitions are spread across multiple translation units, or define things that don't need any definitions in particular translation units (e.g. enum or struct definitions). It could even play macro tricks which means it declares or defines different things each time you include it.

Maybe you mean it's undefined behaviour to include a header file that declares functions that are not defined in any translation unit. I'm not sure even that is true, so long as you don't use those functions. It's definitely not true in C++, where it's only a problem (not sure if it's undefined exactly) if you ODR-rule use a function that has been declared but not defined anywhere. (Examples of ODR-rule use are calling or taking the address of the function, but not, for example, using sizeof on an expression that includes it.)

Re: Undefined Behavior in C and C++ (2024)

#70
post #64

Earlier quoted context omitted.

I was there Gandalf... ;) Console SDKs offering C or C++ APIs doesn't really matter, because you can call C APIs from C++ just fine. So the language choice was a team and engine developer decision, not a platform owner decision (as it should be). From what I've seen, around the late mid-90's, C++ usage was still rare, right before 2000 it was already common and most middleware didn't even offer C APIs anymore. Of cou…

> I was there Gandalf... ;) You were at most in one place. My question was rather, which corners of the industry are you counting? However you are right that one of the killer features of C++ was that it provided a pretty simple upgrade path from C to (bad) C++. It's not just API calls. You can call C APIs from most languages just fine.

My corner of the industry back then was mostly PC gamedev with occasional exploration of game consoles (but only starting with the OG Xbox. But that doesn't really matter much since it was obvious that the entire industry was very quickly moving to C++ (we had internet back then after all in my corner of the wood, as well as gamedev conferences to feel the general vibe).

id Software was kinda famous for being the last big C holdout, having only switched to C++ with Doom 3, and development of Doom 3 started in late 2000.

Post reply on HN