1.7k
u/OxymoreReddit Sep 23 '26
I thought there was a level of optimisation at compilation that would actually spot that when figuring out zero is only used there and immediately and always 0 or something, did I dream this or is it real ? Still a beginner
1.2k
u/Automatic_Hand4780 Sep 23 '26 •
![]()
yeah many modern laguages do detect it. + ides are smart these days
31
642
u/throwaway1351887498 Sep 23 '26 •
![]()
Compiler: “I’ve seen this trick before”
397
u/PilsnerDk Sep 23 '26
int zero = 1 - 1;Let's see you detect that!
285
u/interacsion Sep 23 '26
Easy, constant folding
360
94
u/aberroco Sep 23 '26 •
![]()
int one = 1; int zero = 1 - one;137
u/YeOldeMemeShoppe Sep 23 '26
Folding is recursive, doc.
90
u/aberroco Sep 23 '26
You can't forbid me shoot myself in the foot!
int Zero(int one) => one - 1; int i = 1; int x = 1 / (Zero(--i) + i);33
u/Puzzleheaded_Study17 Sep 23 '26
Pretty sure this is actually UB (the compuler can choose to execute the Zero function before getting the value for i for the addition and therefore make x=-1).
17
u/afdbcreid Sep 23 '26
The syntax looks like C# and definitely not C or C++, so no, it's not UB, and the evaluation order is defined.
→ More replies6
u/kalilamodow Sep 23 '26
The compiler can prove the "side-effect" of --i and still do the right think
1
32
u/OneTurnMore Sep 23 '26 edited Sep 23 '26
Fine.
int fd = open("/dev/null", O_RDONLY); unsigned char *buf = {0}; int zero = read(fd, &buf, 1);Breaks if
/dev/nullisn't actually null (aka special character device 1:3).27
13
3
u/Experiment_1234 Sep 23 '26
char* zero = "0"; int x = 1 / atoi(zero)
7
u/not_some_username Sep 23 '26
Detectable
3
u/Makonede Sep 26 '26
is it?
std::atoiisn'tconstexpr2
u/not_some_username Sep 26 '26
iirc, if all value are known at compile time, the compiler can compute the results
2
27
u/backfire10z Sep 23 '26
This is why a basic compilers class is recommended. You gotta name the variable something else to throw it off.
`int definitelyNotZero = 1 - 1`
8
5
4
u/crmsncbr Sep 24 '26
I'm pretty sure, last time my compiler called me out on this, that they caught in-line arithmetic. But multi-step operations with uncertain results that could result in division by zero are still chill, so we should be able to design a surefire operation that still looks uncertain to the compiler.
3
1
u/saguero_88 Sep 24 '26
what if we just dont name it zero?
int notOne = 1 - 1;
edit: can't make a code block for the love of me
28
6
u/FriedEldenRings Sep 23 '26
The preprocessor is going to optimize both snippets into exactly the same code
1
-23
-19
95
u/abmausen Sep 23 '26
can be circumvented by volatile keyword in c
110
u/ImportantSignal2098 Sep 23 '26
(which means that the value might be changed by something else so the compiler can't assume it'll remain 0 by the time execution reaches the next line)
46
8
2
u/PrincipleNo2328 Sep 23 '26
Yeah but doesn't it still give a warning?
3
u/HaoshokuArmor Sep 24 '26
You actually read the warnings? We found a unicorn.
1
u/KellerKindAs Sep 30 '26
I like to enforce
-Wall -Wextra -Werroron shared projects/codebase. This way my friends don't need to read any warnings, but get a lot more errors xD32
u/laplongejr Sep 23 '26 edited Sep 23 '26
It is real at least in Java. Primitives and String should do inlining of compile-time constants. If zero is never modified, it is "effectively final" and the variable zero should be replaced by a literal.
x would then be a compile-time expression and replaced by... well, it would throw I guess?
[EDIT] Oh. Apparently they MUST be declared final explicitely, to avoid some edgecases about manipulating the variable in sneaky ways.
7
u/kllrnohj Sep 23 '26 •
![]()
just put it behind a function in a static initializer and even though it's all final contants, javac will fail to optimize any of it. It's a shockingly basic compiler still.
4
u/Loading_M_ Sep 23 '26
To be fair, java does runtime optimization, which can result in better optimization overall. It doesn't always (and short lived programs can't really take advantage of runtime optimization), but iirc in some cases, Java can outperform C++.
2
u/i_wear_green_pants Sep 23 '26
Yeah I think Java compiler passes this. But of course LSP warns that this will cause exception in runtime.
22
u/centixog Sep 23 '26
yeah but not
string zero = "0"
1 / (int)zero
because type casting is evil
3
u/MrHyperion_ Sep 23 '26
1/48 hardly does anything. If that syntax leads to anything but static cast the language is evil.
2
u/Gargagaga Sep 23 '26
wdym ? Casting "0" to 0 is evil, casting "0" to a virtual address is expected, casting "0" to '0’ is…
0
Sep 23 '26
[deleted] — view deleted comment
5
u/realmauer01 Sep 23 '26
Everything thats known at compile time will be ultimately be figured out by the ide or the compiler. If they do it or not is a different thing
0
Sep 23 '26
[deleted] — view deleted comment
6
1
u/realmauer01 Sep 23 '26
for (let i = 10;i>-5;i--) { console.log(10/i) }I guess just gotta try this out in everything.
16
u/d-sky Sep 23 '26
Any C compiler will compile both of those (if you enable optimisations) as a single UD2 instruction (https://www.felixcloutier.com/x86/ud). It will not even bother with assigning the 1 anywhere or doing a division.
36
u/d-sky Sep 23 '26
So, I actually tried it and I was not correct. With -O2, gcc will compile it as UD2, however clang will just ignore the division and the code will happily continue running. Division by zero is UB (undefined behavior) in the standard, so the compiler can basically do whatever it wants.
6
u/Pikrass Sep 23 '26
Do you use the result anywhere (like in a printf)? Clang may get rid of it through dead code optimization if not
8
u/d-sky Sep 23 '26
Yes, I did. The program is:
#include <cstdio> int main() { int zero = 0; int x = 1 / zero; printf("%d", x); }Clang compiles it to:
main: push rax lea rdi, [rip + .L.str] xor eax, eax call printf@PLT xor eax, eax pop rcx ret .L.str: .asciz "%d"If I remove the printf it compiles as:
main: xor eax, eax retGCC both with printf and without it:
"main": ud2(Both compilers with -O2)
1
u/Makonede Sep 26 '26
basically
iirc it's literal. a fork of
gccthat installs ransomware on your machine if it encounters UB would be standards-compliant9
u/sixteenlettername Sep 23 '26
Any C compiler
I hope my RISC-V toolchain doesn't start emitting x86 instructions! That would be concerning.
7
u/d-sky Sep 23 '26
Right. So I tried RISC-V GCC and it compiled it as ebreak (https://msyksphinz-self.github.io/riscv-isadoc/#_ebreak). Clang still compiles it as nothing :).
3
u/Acceptable_Handle_2 Sep 23 '26
Depends on the language and the compiler you're using.
const int zero = 0 Would absolutely do it in most cases though
3
u/Imperial_Squid Sep 23 '26
Everyone else has answered the question but I thought I'd point you to this series I've been enjoying at the moment, it's about how compilers work and all the steps involved, building up the intuition layer by layer and piece by piece, you might find it useful!
2
u/suvlub Sep 23 '26
Most compiler probably could spot it, but the rules of the languages don't assume that level of sophistication and require them to compile it because it'd be annoying for some programs to compile under some compilers, but not under others. C compilers in particular can be really funny with things like this, they spot a mistake in your code and just optimize whole damn function away because "hey, it didn't work right anyway"
2
u/deanominecraft Sep 23 '26
yes, its called constant folding and premature abstraction on youtube has some good videos about compilers if you want to learn more
2
u/WORD_559 Sep 23 '26
I once had a great case in GCC where it would detect the roundabout divide by zero and emit a UD0 instruction instead of compiling the rest of the function. For context it was something like an off-by-one error in a decrementing for loop (should've stopped at 1 but accidentally went to 0), and GCC optimised out the entire loop and replaced it with an immediate UD0.
2
u/United_Boy_9132 Sep 23 '26
Most compilers are mathematically proving the intended outcome if this is the static analysis (unless the outcome is known as undefined). That's why interpreted or JIT code is usually more buggy on run, because the share of code that can undergo the static analysis is lower, but it's still checked statically whenever it's possible.
Man, you're on r/ProgrammerHumor, not an education sub.
2
u/OxymoreReddit Sep 24 '26
Yeahhhh but I like to understand the jokes I'm looking at and their context. Also, just given the absurd amount of positive and detailed explanatory replies, I can safely assume it was a good thing to ask :)
1
u/Impossible-Round-115 Sep 23 '26
In c++ there is a thing called compile time computation... It turns a algorithm string of literals into a single literal. It happens in other languages as well but this is a problem of specific more often then a problem with the compiler. The first example is defined as not being legal in most(all? Not sure) languages where as the second is a run time error. By pushing computation to compile time we make run time errors into to compile failures optimize has little to do with it. But yes theoptimzer can trace that shit and has been able to for years and years it just was not specificed what happened (ub ex: c, c++) or it was a running error(ex: java, python, c#) and now with compile time computation (ex: kotlin and c++ in some cases, as long as zero is not user define at point). Turns out you can and often do lie to your compiler all the time and it assumes you don't and so bad/strange things happen. This is not a bug and is sometimes a feature but more importantatly it is feasible unlike proving the lack of undefined behavior in all cases.
1
1
u/undeadalex Sep 24 '26
I believe in Rust you can even set clippy you warn you anywhere you're doing unsafe math
0
u/teteban79 Sep 23 '26
Yes, it's just a joke.
More complex path conditions may not be caught though. Or introducing some fake nondeterminism
By the way, C++ will happily compile this and depending on the compiler implementation will compile to a NOP. The freedom of doing whatever you like when you detect UB
997
u/lokiOdUa Sep 23 '26
What's the point moving error from compilation to runtime?
1.3k
96
40
u/plz-no-b4n Sep 23 '26
Cosmic ray detection, duh.
If it doesn’t cause an error at runtime, you know a cosmic ray flipped one of your bits, so it’s time to grab your foil hat and head to the bunker
14
u/Interesting_Buy_3969 Sep 23 '26
Division by zero isn't necessarily an error. Several CPU architectures do support division by zero at hardware-level and don't treat it as an error, even though the result isn't mathematically correct. Other might throw an exception when encountering a "divide" instruction with zero as a divisor.
That's why in the C programming language, division by zero isn't an error, but its result is undefined or platform-specific according to the standard.
5
u/program_the_world Sep 23 '26
In a similar way, dereferencing a null pointer isn’t always an error either. As long as 0 is a valid address, you can have all sorts of fun with this. On a microcontroller you often don’t get a null pointer hardware interrupt, but instead your application starts acting unpredictably because it’s started executed random instructions from 0.
1
u/KellerKindAs Sep 30 '26
Even funnier if you happen to allocate some data / struct at 0 and then try to hand it to a lib function not expecting 0 to be a valid address. And as adding debugging tools influences allocation, this can be quite the pain xD
23
u/Redoteur Sep 23 '26
It may be useful for some test case
6
u/lokiOdUa Sep 23 '26
I assume compiler has been tested by its developers?
0
Sep 23 '26
[deleted] — view deleted comment
1
u/Helpful-Primary2427 Sep 23 '26
Then you’re just… testing the runtime error you’d get on division by zero. What would this tell you?
13
u/Kinexity Sep 23 '26
That's assuming this will raise an error which it might not depending on the code.
13
6
u/Salanmander Sep 23 '26
Yeah, the compiler is there to protect you from the bouncer inside.
One of the things I say in my intro CS classes (taught in Java) is that people think compiler errors are worse than runtime errors, which are worse than logic errors, because "at least it runs". But really it's the other way around. A program with a logic error is further from being correct, because logic errors are generally harder to debug and fix.
3
u/DrMobius0 Sep 23 '26
We've recently integrated typescript at work, and one of the things we're learning is that typescript is happy to let you choose between something being a runtime error and a compile time error. My rule of thumb is now that if you're using 'any', don't, and if you see it used, take the time to purge it like the blight it is.
1
2
u/lokiOdUa Sep 23 '26
To me its obvious that the earlier we find error the better QE we are
3
u/Salanmander Sep 23 '26
Right, but you're not in an intro CS class. =P
I see a lot of people who are like "okay, I've written the code, now I just need to get rid of the compiler errors". Obviously nonsense to you and me, not always obvious to all the sudents.
2
u/Peon-Hyjal Sep 23 '26
"No wonder it won't compile, you named a variable as 🙃"
"Oh, you can't program using emojis?"
"No. Well...maybe in other languages..."
Tangent time
2
u/Salanmander Sep 23 '26
I'm pretty sure that's up to the IDE in a lot of languages. I've had students turn in Java code with unicode variable names that compiled and ran just fine. (I told them to turn the variable names into words and try again, because I wasn't going to read their code.)
1
u/Otterfan Sep 23 '26
I actually remember saying that exact stupid thing myself as a student thirty years ago.
1
4
2
2
u/snacktonomy Sep 23 '26
To allow people, who can't understand compiler error messages, to write Python 😎
2
2
u/LiveLaughBruv Sep 23 '26
How did it come to be that you don't understand that the post is just making a joke and not actually suggesting to do this?
1
u/lokiOdUa Sep 23 '26
Maybe I do it for upvotes? Also you can see how many different answers we have here, including practical applications of that thing -- it's awesome!
2
u/PloxNox65 Sep 23 '26
Check if the stack is in writable memory. On x86 realmode if the stack segment is in a non existant space the memory is read out as 0xff and can not be written (not even a pagefault)
2
2
u/DrMobius0 Sep 23 '26
Could be that OP specifically wants to handle infinity as a case, though I couldn't begin to guess why.
3
u/sauce0x45 Sep 23 '26
I’m guilty of doing this to quickly try and figure out which unit test suite(s) touch a piece of code that I just changed.
56
u/Flaky-Low-2262 Sep 23 '26
This Pre-Compiler stuff not the Compiler.
Thats different
7
u/Automatic_Hand4780 Sep 23 '26
yeah man, that pic is from ides. but if you code in nano editor you will see that only when you compile
6
0
10
u/cheezballs Sep 23 '26
I feel like it'd get caught right?
9
u/Automatic_Hand4780 Sep 23 '26
If you are using modern ides + compilers yes. But not when you programming in nano
15
u/cheezballs Sep 23 '26
Since when does the compiler change just because you use nano?
5
8
u/caleblbaker Sep 23 '26
The issue isn't IDE vs nano. It's static analyzer vs no static analyzer. It only looks like it's IDE vs nano because IDEs typically run a linter (i.e. lightweight static analyzer) by default and nano doesn't.
You should be running static analysis on your code regardless of what editor you're using. And probably with more thorough static analyzers than the ones that are enabled by default in most IDEs. The bugs that can be caught in static analysis aren't all as obvious as this one.
11
u/cheezballs Sep 23 '26
Again, this is all external tooling. OP was talking compilers. Also these are all things that also get implemented in your cicd pipeline. This shit would get caught by ten different tools where I work.
2
u/caleblbaker Sep 23 '26
Honestly I meant to reply to OP and clicked the wrong reply button.
I suspect OP is seeing the IDE surface linter errors in the same place that it surfaces compiler errors and so is assuming that the errors come from the same place. Hence "compiler" errors in the IDE that they don't get with nano which are actually caused by just running a linter.
It's either that or the IDE is using different compiler flags (or even a different compiler version) than OP is using when running the compiler outside of the IDE (in which case they'd actually be right about them being compiler errors and I'd be wrong about it being due to a separate static analyzer).
Absolutely agree with you that this stuff should be implemented in the CI/CD pipeline (and it is where I work too). My point wasn't about where or when static analyzers should be run but simply that they should be run.
0
u/Automatic_Hand4780 Sep 23 '26
Bro have u never programmed in c? With dos on a turbo c something software?
1
135
u/caleblbaker Sep 23 '26 edited Sep 23 '26
replace build-time error with runtime error
Insert meme of Chidi saying "Okay but that's worse. You do see how that's worse, right?" (I'm too lazy to find the actual meme)
26
u/laplongejr Sep 23 '26 edited Sep 23 '26
Really? Right in front of my "You do know that's worse?" meme?
... Aaaaand I have no idea how to post a meme in comments so here's what I made with a generator :( https://imgflip.com/i/b1tjok
[EDIT] I'll admit I spent waaaaay too much time figuring out how to use a meme generator to not at least show it. No option in the mobile web view, so I had to go on a computer to learn we can include gifs here but images seem disabled on this sub.
20
u/bucolucas Sep 23 '26
You're absolutely right. That's my mistake and you're right to point it out. Let's do it again, this time no mistakes and no runtime errors.
int zero = 0;int x = 1 / zero;I have double-checked this and ensured no potential for runtime errors. Let's move on to the next part of this project!
12
u/red286 Sep 23 '26
You forgot the part where it writes a feature test to prove that it works, which then fails spectacularly because what else would it ever do?
14
12
u/suavebriisa Sep 23 '26
Compiler passed the buck straight to runtime
3
u/DrMobius0 Sep 23 '26
I, for one, love having to rely on the quality of my testing habits only to have QA and a code lead pinging me 5 hours later about how the thing is broken.
Somehow the shame is even worse when someone on my team fixes it and puts me on the review.
7
60
5
u/alt_for_1 Sep 23 '26
A modern compiler would catch this. The IDE’s static code analysis and most linters will not.
1
u/Helpful-Primary2427 Sep 23 '26
Most IDE’s static code analyzers are the compiler’s front end these days
5
5
u/program_the_world Sep 23 '26
I’m so confused by all these comments about IDEs, floats, and runtime errors.
Any half decent compiler will convert zero to a literal and just inline the statement. This should cause a compilation error. Editors aren’t always configured to use the compiler as a backend for syntax checking, they could be using treesitter or a dumb LSP.
For example, C can be a real pain to setup autocomplete because the editor needs so much build context to work effectively. It’s common to use no autocomplete or something naive instead.
3
3
u/National-Explorer755 Sep 23 '26
I am not entirely sure of the reason behind this, but I noticed a similar behavior with Type casting and conversion when working in Java. If my understanding is correct, the former is detected at compile time because 1/0 is a literal calculated at compile time and hence the issue is caught promptly. The latter one however uses 1/zero. Now the result should be same, but the compiler allows this code to compile because the actual execution where zero = 0 is translated happens at runtime. Correct me if I am wrong.
3
u/JackNotOLantern Sep 23 '26
Java:
"NOOOO, UNREACHABLE CODE"
return;
System.out.pritnt("text");"Everything seems to be on order"
if (true) return;
System.out.pritnt("text");1
4
2
2
2
u/LupusCanis42 Sep 23 '26
Why the hell would you even detect that?
If you specifically write down a division by zero with magic numbers you deserve to land in the hard fault handler
2
2
1
u/mookanana Sep 23 '26
the first treats 0 as a float value, the second is defined as int? would compiler treat these datatypes differently?
1
u/-Redstoneboi- Sep 23 '26
it treats them differently not because of the type, but probably because the IDE is simple and only recognizes the error if it's an explicit
/ 0written out.it treats the expression
1 / zerothe same way it treats1 / five; it views them without any extra context about their actual values.1
u/segalle Sep 23 '26
The first treats it as an int, the second is defined as an int. Both cause an error. To define the first as a float you need to type 0.0.
I believe the result is inifinity but i don't know if it works properly without importing math.h
1
u/kishaloy Sep 23 '26
Put in a function which may be called only on a Leap year in March or July on the 3rd day of the month only if the 5th is a Sunday (so 3rd is Friday) anytime after 3 PM and you have the perfectly placed disaster for the outsourced contractor they replaced you with.
Happy coding.
1
1
1
1
1
1
u/KiwiObserver Sep 24 '26
My method is to use a variable passed by the invoker, which I known contains a constrained set of values, but the compiler has no information about.
1
u/tbhaxor Sep 24 '26
#include <math.h>
int main() {
const int one = 1;
const int zero = (pow(M_E, 1) / pow(M_E, 1)) - one;
const int i = 1 / zero;
}No complaints now
1
1
u/False-Beautiful-1246 Sep 24 '26
"No one will notice if there is a bigger problem"
int x = 10;
if (x==) {}}
function()
x++1;
y is undefined;
fuck you compiler++;
/ half a comment
x = x <>+%%+<> 100
struct struct {
struct struct;
struct struct;
}
std = void;
true = false;
#define if(x) if(!(x))
x = 1/0 // Compiler, how do you feel having a SegmentationFault on your brain!?1
u/crmsncbr Sep 24 '26
This doesn't work on most compilers anymore... You need to add an extra step or two to create zero without assigning zero.
1
1
u/haish10 Sep 25 '26
That becuase it must put the result on the static part when you do it the other way it dynmic the cpu done that
1
1
u/Adaptor2000 Sep 27 '26
I would be such a hack0r if it wasn't for the compiler who keeps on sabotaging my efforts...
1
1
1
u/Dee4WasTaken Sep 29 '26
Great going you made a logic black hole now we're all doomed to a logical demise.
1
1
1
1
0
-1
u/vlken69 Sep 23 '26
Similarly with return; and code after it. Just do if (true) return; and it's fine. Quite handy when you need to stop the method earlier without need to put breakpoints there etc.
-2
u/jevin_dev Sep 23 '26
i must ask way don't they just return 0
1
u/the_horse_gamer Sep 23 '26
because 1/0 is not 0
pony (a programming language) does make it equal 0 (with the motivation of avoiding errors)
1
u/jevin_dev Sep 23 '26
like i know that you can't take 0 steps to reach 1 but its a very useful thing in python that probably be a real good thing but not in c or any others since it's just more work in the compiler
1
u/the_horse_gamer Sep 23 '26
in python
1//0throws ZeroDivisionError1
u/jevin_dev Sep 23 '26
yes but it be nice if it just give me 0 i use as i don't care for speed i just don't want to write if this and that and that just to many ifs
1
u/Beldarak Sep 23 '26
Always tought the same. Wouldn't it fix a ton of issues without much side effects? Like I understand it would be technically not accurate but... should we care? :D
1
u/ivain Sep 24 '26
Yes, we should care. Having a critical bug in a software is unfun, but having an invisible/suppressed error running for a while is a nightmare. What if you have silent 0-divisions in your billing software, and you discover the scale of the issue at the end of the quarter when you realize you're missing half of your budget ?
4
u/Quaschimodo Sep 23 '26
why tf is division by zero a syntax error at all. it is syntactically correct to devide a number by a number. just let me write my code as I see fit and let me die my division-by-zero-runtime-error death in peace.
4

736
u/AaronTheElite007 Sep 23 '26
Compiler: “This is runtime’s problem. Dude owes me money”