Live data from Hacker News

Everything in C is undefined behavior

blog.habets.se

641–650 of 748 posts

Re: Everything in C is undefined behavior

#641

Earlier quoted context omitted.

I'd say the unaligned pointer one is the language's fault. The language should not let you create an an invalid pointer, or at least warn you when you are doing so. OTOH one could argue that creating truly portable programs is not possible since a programming language is a leaky abstraction - different machines have different endianness, different alignment requirements, different amounts of memory, etc. One could ar…

> The language should not let you create an an invalid pointer, or at least warn you when you are doing so completely agree!

That's a nonsensical statement, a language cannot warn you, only a compiler can (-Wcast-align). The compiler can also decide what is and isn't an invalid pointer, this way the language avoids leaky abstractions.

Re: Everything in C is undefined behavior

#642
> We need some way of fixing UB at scale, without committing AI slop nor overwhelming human reviewers.

Write compiler which will define all this behavior. Usually people forget that UB exists only in standard. In practice it is always defined.

P.S. of course, while your hardware + firmware staying unchanged

P.S. not always defined in documentation - I mean defined in e.g. code

Re: Everything in C is undefined behavior

#643

Earlier quoted context omitted.

What if the wrapped index is used to construct an invalid pointer? It might be possible, not sure. What if the integer is used to read the wrong data from disk, or corrupt data on disk by writing to the wrong location?

> What if the wrapped index is used to construct an invalid pointer? Constructing an invalid pointer in rust is UB, yes, but integer wraparound is not. > What if the integer is used to read the wrong data to a disk, or corrupt data on disk by writing to the wrong location? Then it is a very bad bug. > What if the program controls a nuclear power plant and the integer causes the control system to fail, causing memory…

> Constructing an invalid pointer in rust is UB

no, it is dereferencing, not constructing, an invalid pointer, that is UB. there is even a safe function provided to construct an invalid but non-null pointer: `https://doc.rust-lang.org/stable/std/ptr/fn.dangling.html`

Re: Everything in C is undefined behavior

#644

I have never in my 20 years of writing C heard so much about undefined behavior as I have in the past 6 months on Hacker News. It has never entered the conversation. You write the code. If it doesn't work, you debug it and apply a fix or a workaround. Why does the idea of undefined behavior in C get to the front page so consistently?

Exactly, you write for your target, not some imaginary spec. The spec is only as useful as to predict what your target roughly does, it's not normative.

Compilers might have bugs where the spec is supposed to work but it doesn't, and many extensions without standard equivalents, or implementation-specific behaviour where undefined things in the standard do get assigned a meaningful outcome.

Re: Everything in C is undefined behavior

#645

I have never in my 20 years of writing C heard so much about undefined behavior as I have in the past 6 months on Hacker News. It has never entered the conversation. You write the code. If it doesn't work, you debug it and apply a fix or a workaround. Why does the idea of undefined behavior in C get to the front page so consistently?

There was a similar rush of articles like this a few years ago.

tl;dr: C defined language semantics, and leaves some behavior undefined. Each system that C is ported to has the ability to define the behavior however it wants.

This blows the mind of PL folks every decade or so.

It’s cool that we have portable methods and formal language semantics for stuff like memory fences and atomics now, but that sort of thing worked fine in C back in 1970 (or else unix would not have worked). You just needed to read the target machine’s manual when porting stuff.

The modern version is arguably better, but also arguably worse. Does anyone else remember when the JVM got this stuff wrong, making safe multithreaded code impossible, and then later had to break compatibility with the language spec?

You could claim that we can’t trust hardware folks to get instruction semantics right (this is demonstrably true), but duplicating and slightly modifying the specs in your language spec doesn’t actually fix the underlying hardware bugs.

Yeah, getting old… I’ll go find a cloud to yell at.

Re: Everything in C is undefined behavior

#646

I have never in my 20 years of writing C heard so much about undefined behavior as I have in the past 6 months on Hacker News. It has never entered the conversation. You write the code. If it doesn't work, you debug it and apply a fix or a workaround. Why does the idea of undefined behavior in C get to the front page so consistently?

Excuse me, what? I was writing both C and C++ 20 years ago, and UB was a huge part of the conversation (and the curriculum) back then as well. There were a few high-profile "scandals" around GCC 3.2 (IIRC) because the compiler finally started much more aggressively using UB in optimizations, which was a reason that lots of people stayed on GCC 2.95 for a very long time. GCC 3.2 came out in 2002.

“More aggressively using UB” isn’t the right way to think about it.

In the C ecosystem, the compiler gets to define what UB means. They broke compatibility with their previous UB semantics, then blamed the language spec.

Re: Everything in C is undefined behavior

#647

Earlier quoted context omitted.

It's indistinguishable from unspecified behavior, not from undefined behavior. Unspecified behavior has to pick from a finite list of allowed behaviors. Undefined behavior can do anything .

A program with corrupted state can essentially do anything. Yes it's still a question of run-time checks the runtime has to protect against it. But the compiler is probably deriving a lot of assumptions from the assumption that there wasn't overflow.

“Undefined behavior” is a term of art in programming languages that means something more specific than “the program may do something odd.”

The compiler is not allowed to derive any assumptions from it. It only could if it were UB.

Re: Everything in C is undefined behavior

#648

Earlier quoted context omitted.

No. An integer getting deterministically set to an unintended value is a bug. A bug is not the same thing as UB. (Even if it were non-deterministic, it would still not be anything like UB.) It's not the same ballpark, not even the same sport.

What if the wrapped index is used to construct an invalid pointer? It might be possible, not sure. What if the integer is used to read the wrong data from disk, or corrupt data on disk by writing to the wrong location?

> What if the wrapped index is used to construct an invalid pointer?

Using that pointer would be UB, but that is UB, not the addition.

> What if the integer is used to read the wrong data from disk, or corrupt data on disk by writing to the wrong location?

That is a bug, but it is not undefined behavior.

Re: Everything in C is undefined behavior

#649
post #403
post #113

Yes there is tons of surprising and weird UB in C, but this article doesn't do a great job of showcasing it. It barely scratches the surface. Here's a way weirder example: volatile int x = 5; printf("%d in hex is 0x%x.\n", x, x); This is totally fine if x is just an int, but the volatile makes it UB. Why? 5.1.2.4.1 says any volatile access - including just reading it - is a side effect. 6.5.1.2 says that unsequenced…

> In C, we can have a data race on a single thread and without any writes! You need to distinguish between a UB and a race, and I think that's something that discussions of UB miss. Take any C program and compile it. Then disassemble it. You end up with an Assembly program that doesn't have any UB, because Assembly doesn't have UB. UB is a property of a source program, not the executable. It means that the spec for t…

> You end up with an Assembly program that doesn't have any UB, because Assembly doesn't have UB.

I guess that's true if you think of assembly as a more readable form of machine code, but from a practical sense I'd argue that assembly inherits the undefined behaviors of the architecture it represents and the implementations of that architecture it actually builds for.

IIRC the OG Xbox security was broken partially as a result of undefined behaviors in x86 where the AMD CPUs that were used in early development would crash or throw an error or something when execution reached the end of the memory space but the Intel CPU they switched to instead just rolled over and kept executing from 0.

Re: Everything in C is undefined behavior

#650
post #586
post #475

Earlier quoted context omitted.

> People just don't use this because they want to write "portable" "standard" C Something that bothers me is the Venn diagram of people that think abstraction is slow and error prone and people that only write portable C. How many C implementations do you actually need to compile against? I don't think I've seen more than 3 outside Unix software from the 90s. Using non portable extensions is in fact totally doable fo…

Back when I still wrote C at work, it meant Aix xlC, HP-UX aCC, Solaris Forte, Red-Hat Linux GCC, Windows MSVC and C++ Builder. Nowadays most are indeed clang and GCC forks, or MSVC.

That's what I mean, I've seen enough autoconf "checking for " noise to know it's mostly pointless in this day in age.
Post reply on HN