Live data from Hacker News

Everything in C is undefined behavior

blog.habets.se

51–60 of 748 posts

Re: Everything in C is undefined behavior

#51
The examples aren't really undefined behavior. They are examples that could become UB based on input/circumstances. Which if you are going to be that generous, every function call is UB because it could exceed stack space. Which is basically true in any language (up to the equivalent def of UB in that language). I feel like c has enough actual rough edges that deserve attention that sensationalism like this muddies folks attention (particularly novices) and can end up doing more harm than good.

Re: Everything in C is undefined behavior

#54
post #22
post #7

Earlier quoted context omitted.

> but that the consequence of this should be somewhat bounded or as expected for the target machine. Aren't "unpredictable results" and "no requirements" contrary to the idea that the behavior would be "somewhat bounded"?

Notice though "ignoring the situation" thru "documented manner characteristic of the environment". Even though truly you can read this in an uncharitable way, you could also try and understand the intent of this paragraph, and I think reading it for its intents is always the best way to interpret a language standard when the wording is ambiguous or soft, especially if you're writing a compiler. I don't think you coul…

Reading for intent is pragmatic.

Reading adversarially is what people do who are looking for ways that something can be abused, from an offensive or defensive position.

Personally I am tired of the entire topic.

Re: Everything in C is undefined behavior

#56
post #8

The problem of UB is not really that it may crash in some architecture. The real problem is that the compiler expects UB code to NOT happen, so if you write UB code anyway the compiler (and especially the optimizer) is allowed to translate that to anything that's convenient for its happy path. And sometimes that "anything" can be really unexpected (like removing big chunks of code).

One example along this path as an example is that every function must either terminate or have a side effect. I don't think one has bitten me yet but I could completely see how you accidentally write some kind of infinite loop or recursion and the function gets deleted. Also, bonus points for tail recursion so this bug might only show up with a higher optimization level if during debug nothing hit the infinite loop.

Re: Everything in C is undefined behavior

#57
post #18
post #16

Yet another push to use LLMs after casting fear. Now it should be illegal not to use LLMs. A good start of the day. (I hope casting fear is not UB)

The irony is unmistakable.

There is nothing ironic in letting an llm have a pass at identifying potential UB and other correctness issues in C code.

I say this as an experienced C developer.

Re: Everything in C is undefined behavior

#58
post #8

The problem of UB is not really that it may crash in some architecture. The real problem is that the compiler expects UB code to NOT happen, so if you write UB code anyway the compiler (and especially the optimizer) is allowed to translate that to anything that's convenient for its happy path. And sometimes that "anything" can be really unexpected (like removing big chunks of code).

Removing code paths that the programmer has explicitly laid out in the source code should be made a hard compile error unless the operation has been tagged with an attribute (anyone who wants to add the unsafe keyword to C? ). Another commenter suggested using LLMs, but I disagree. Having clangd emit warning squiggles for unchecked operations (like signed addition) would be a good start.

> Removing code paths that the programmer has explicitly laid out in the source code should be made a hard compile error unless the operation has been tagged with an attribute (anyone who wants to add the unsafe keyword to C? ).

Dead code elimination is essential for performance, especially when using templates (this is basically what enables the fabled "zero cost abstraction" because complex template code may generate a lot of 'inactive' code which needs to be removed by the optimizer).

The actual issue is that the compiler is free to eliminate code paths after UB, but that's also not trivial to fix (and some optimizations are actually enabled by manually injecting UB (like `__builtin_unreachable()` which can make a measurable difference in the right places).

Re: Everything in C is undefined behavior

#59
post #10

In C / C++ there are two kinds of undefined behaviour. One is where there is written in standard what UB is. Another one is everthing else that is not in standard.

Technically, that's only one kind, because it's written in the standard that anything not mentioned in the standard is undefined behavior.

[deleted]

Re: Everything in C is undefined behavior

#60
post #5

From the ANSI C standard: 3.16 undefined behavior: Behavior, upon use of a nonportable or erroneous program construct, of erroneous data, or of indeterminately valued objects, for which this International Standard imposes no requirements. Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner c…

> Is it just me or did compiler writers apply overly legalistic interpretation to the "no requirements" part in this paragraph?

I've (fruitlessly) had this discussion on HN before - super-aggressive optimisations for diminishing rewards are the norm in modern compilers.

In old C compilers, dereferencing NULL was reliable - the code that dereferenced NULL will always be emitted. Now, dereferencing NULL is not reliable, because the compiler may remove that and the program may fail in ways not anticipated (i.e, no access is attempted to memory location 0).

The compiler authors are on the standard, and they tend to push for more cases of UB being added rather than removing what UB there is right now (for exampel, by replacing with Implementation Defined Behaviour).

Post reply on HN