3 ms·
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 co
by inkysigma 5mo ago
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.
- account42 5mo agoInfinite loop without side effects == program stuck and not responding on user input and not outputting anything. That's not something a useful program will ever want to do.
- xigoi 5mo agoThe problem is when you accidentally write an infinite loop. In a different language, you run the code, see that it gets stuck and fix it. In C, the compiler may delete the function, making it hard to realize what is happening.
- account42 5mo agoThis is not a problem that C or C++ programmers actually encounter, ever.
- ncruces 5mo agoI actually encountered it a couple weeks ago. Can you spot the infinite loop in this function? char* strcpy(char* restrict d, const char* restrict s) { stpcpy(d, s); return d; } I'll help. A call to `stpcpy` that ignores the return value can be swapped with a call to the (more likely to be optimized) `strcpy`. Since that's infinite recursion, and there is no forward progress, it's undefined behavior and anything goes. This isn't just theory, it actually broke things in practice for me.
- rssoconnor 5mo agoNaming an externally linked function with the prefix "str" is by itself UB since that prefix is reserved for <string.h>.
- ncruces 5mo agoRight. I am doing a standard library replacement, and forgot I needed to compile freestanding. Oops. My bad. So `str` and `mem` are reserved. But then so are `to` and `is` (by <ctype.h>). Just forget about having a function named `is_valid_user`. And so are `mtx_`, `cnd_`, `thrd_`, `atomic_`, `memory_`... Which is why... everything in C is UB.
- 1718627440 5mo agoNote, that this is not true for C.
- Certhas 5mo agoNot true, C++ made it so trivial infinite loops are not UB because it turns out they do have legitimate uses. https://lists.isocpp.org/std-proposals/2020/05/1322.php https://lists.isocpp.org/std-proposals/2020/05/1322.php https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2809r3.html https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p28...
- account42 5mo agoYes, the C++ committee has been making some stupid decisions lately. This is not the only one. Low level platform-specific code that needs to hot spin until an interrupt happens can use assembly for that part which it will need to do for the interrupt handler anyway.
- TuxSH 5mo agoYou don't even need to use assembly for this, the wait for interrupt typically involves side effects.
- zarzavat 5mo agohttps://9p.io/sources/plan9/sys/src/libc/9sys/abort.c https://9p.io/sources/plan9/sys/src/libc/9sys/abort.c
- account42 5mo agoThis is already UB without an infinite loop.
- deleted 5mo ago[deleted]
- 1718627440 5mo agoThat's only true in C++ though, not in C.
- dzaima 5mo agoC does allow unconditional infinite loops (e.g. "while (1) { }" isn't UB) but still is UB if the controlling expression isn't constant (e.g. "while (two < 10) { }" is UB if two is a variable less than 10)
- marcosdumay 5mo agoThere is that famous example where when you write an infinite loop last thing in your main, a function that you never called runs instead.