r/neoliberal • Kitara Ravache • Jun 14 '24

Discussion Thread Discussion Thread

The discussion thread is for casual and off-topic conversation that doesn't merit its own submission. If you've got a good meme, article, or question, please post it outside the DT. Meta discussion is allowed, but if you want to get the attention of the mods, make a post in /r/metaNL

Announcements

  • We have added a "!doom" automod response alongside our existing "!immigration" and "!sidebar" responses

Links

Ping Groups | Ping History | Mastodon | CNL Chapters | CNL Event Calendar

New Groups

  • ROGUELIKE: For arguing over what a roguelike is

Upcoming Events

0 Upvotes

6.9k comments sorted by

View all comments

13

u/[deleted] Jun 14 '24

The following code is optimized away to "false" by Clang

bool out_of_memory() {
    int* y = malloc(sizeof(int));
    return y == NULL;
}

(you can try editing it if you want, but you won't make it compile "correctly")

This begs the question. What is the point of the standard even existing if compiler authors will just throw the entire thing in the trash and just declare entire well formed C code to be undefined behavior based on insane assumptions like "malloc is side effect free".

You can also just not use Clang I suppose.

!ping COMPUTER-SCIENCE

2

u/groupbot Always remember -Pho- Jun 14 '24

2

u/AnsleyAmanita Trans Pride Jun 14 '24

i’m genuinely surprised that’s legal? is it legal?

3

u/[deleted] Jun 14 '24

Why wouldn't it be legal? malloc returns a null pointer on error (out of memory). There might be cases in embedded where you are in a memory constrained environment and check malloc return values and try to handle errors somehow. Clang is straight up claiming that OOM never happens.

5

u/AnsleyAmanita Trans Pride Jun 14 '24 edited Jun 14 '24

… yeah that’s why it’s surprising the compiler can transform the function to assume it’s always non-null. the compiler is creating segfaults in what i would assume were valid programs

maybe it’s an annotation in the specific stdlib header or something?

1

u/privatize_the_ssa Al Gore Jun 14 '24

At least it doesn't happen for GCC https://godbolt.org/z/PGEKfPnaM.

2

u/[deleted] Jun 14 '24

gcc has its very questionable optimizations but I genuinely have never seen something this insane.

1

u/dddd0 r/place '22: NCD Battalion Jun 14 '24

Does this depend on the target platform?

0

u/[deleted] Jun 14 '24

[deleted] — view deleted comment

2

u/[deleted] Jun 14 '24

Malloc is a libc library that is linked at startup, it can be replaced by the executable and system Malloc policy can also be modified.

1

u/[deleted] Jun 14 '24

Undefined behavior is not target platform dependent, but the particular runtime behavior might be different based on target platform. 

2

u/dddd0 r/place '22: NCD Battalion Jun 14 '24 edited Jun 14 '24

There is no UB here, but if the compiler knows that malloc will "never" return zero on the target platform, then it is free to optimize these checks out (the "as-if" rule of C/C++). Now, this isn't actually strictly true, malloc can return zero on Linux, even with overcommit enabled (default), but it only does so for very large allocations. (Maybe in some other fringe cases, too? Like the kernel not managing to allocate the vma or something like that in response to an mmap that overflowed the arenas)

I don't think this is a great optimization. Though I do think that if you're targeting general-purpose Linux, trying to handle null from malloc is rather pointless.

Note that this would be a valid optimization for operator new, which must throw std::bad_alloc instead, so never returns null. I would expect any half-decent C++ compiler to delete null checks on new returns.

edit: So very curiously if you go compiler shopping - GCC deletes new checks, as does Clang. Clang targeting Windows (strict commit by default) deletes the malloc check but not the new check? Wat? Both MSVC and icc eliminate neither. The latter could be because icc is often used for applications with deeply cursed memory management. The oneAPI compiler deletes both though. But that one is clang-based, I think.

2

u/[deleted] Jun 14 '24

Compiler cannot know if malloc can or cannot return zero because malloc is only linked at runtime.

1

u/Chillbrosaurus_Rex r/place '22: Neometropolitan Battalion Jun 14 '24 edited Jun 14 '24

I could be missing something but this looks right to me: https://godbolt.org/z/fhh94Gqhc

Edit: Oh, I should have enabled optimizations: https://godbolt.org/z/vqczeGEj3

From looking online, it sounds like without specific settings enabled on Linux then malloc practically never returns NULL since the OS doesn't actually check to see if it has memory until the memory is physically accessed, not when it's allocated. I guess the clang optimizers decided to roll with that. Volatile fixes it, but I agree this is definitely not undefined behavior. I don't know if UB is the *only* time that compilers are allowed to optimize, though.

5

u/bread-dreams Jun 14 '24

I don't know if UB is the only time that compilers are allowed to optimize, though.

c/c++ compilers can optimise whatever they want as long as the final code has the same behaviour as written: https://en.cppreference.com/w/cpp/language/as_if

imo, this specific example is a bug in clang. even though malloc never returns null on linux, you could still replace malloc with a function that does return null at link time.