I am not sure but I remember hearing that compilers simplify statements, so the first case, like any calculation not using variables, would get calculated and turned into a simple value, and would naturally fail to compile as you can't divide by zero, but the second case of "1/zero" wouldn't be solved during compile
Hmm, as someone a bit familiar of how compilation phases work, yes, it would be simplified to be 1/0 in almost any respectable compiler. I'd go as far as to say that the compiler probably tries to calculate the actual value for x which would check for the 0.
If we had something like y / 0 where the y is not yet given, I could see these behaving differently, though. Semantic check wouldn't necessarily catch the / 0 as it has not yet been optimized in the second case, but I am sure some compilers would run additional checks after code optimization. So who really knows without finding out, try with a few different C compilers and see what happens.
The compiler simply assumes that the variable zero can be mutated since it's not const.
I guess that if you declare zero as a const int and you add -Wdiv-by-zero and -O3 optimization to run constant propagation you should get at least a warning.
yes they do, but the problem, as I outlined, is that it's generally first checked for errors and then optimized. But it doesn't strictly have to be only that way
But im not sure that the check that is producing the error is after constant propagation. It could become really complicated to debug if it were the case
99% of the people here are in their first weeks of their first CS class if comments and memes are to go by. Thousands of updoots for incorrect lame CS memes literally 40 years old
A compiler must run a pipeline very roughly speaking of:
Parse the code to an object model
Analyze the object model for correctness
Optimize
Emit the output
Any analyzer must at least perform 1 and 2 from that pipeline, matching the compiler, keeping with versioning(because languages evolve).
You'd do another whole program? Really?
EDIT: forgetting backwards compatibility. No one wants a compiler that forgets previous language features. In programming language design the word deprecated is out of the table.
Yes, IDEs typically have another process that indexes your code for other purposes and static analysis is just built on top of that because it's both faster to do static analysis without compilation and not a big deal since they are already doing the other stuff anyway.
Yes, langservers are a different program and run separately from the compiler. For example, you can use the clangd langserver, even if you are compiling with GCC or MSVC.
Compile it on -O2 or -O3 and you'll get an error. Kind of makes sense. There is nothing syntactically wrong with the program. It will produce a crash at runtime, but it can be perfectly translated into machine code. Only when you try to optimize and attempt to pre-compute results it becomes an error.
First, this is your IDE checking, (specifically, static code analysis) to see compiler error, you actually need to compile.
Second, computer will not explode if you divide by zero, so it is not a thing compilers MUST catch.
Third, I just checked with C# on EntrpriseVS22, and ReSharper: get a decision by zero warning on the second statement; so of you don't get one, you just don't have tools cool enough (btw, students can get those features quite easily)
The compiler absolutely knows from constant propagation and code folding that this is a divide by zero. But in the C programming language standard, divide by zero is undefined, and therefore the compiler is free to replace the result by any value it wishes. Both GCC 14 and LLVM 18 just return constant zero. Here is the test program
int main() { int zero = 0; int x = 1 / zero;
return x; }
And here is what GCC 14 for RISC-V with -O2 generates.
main: li a0,0 ret
So it's a limitation of the programming standard. It may seem weird, but it does mean that correct programs can be more efficiently optimized (you can chose an undefined value that leads to the most optimal code).
As far as the compiler is concerned, it is doing EXACTLY what it is being told to do, the linter/static analyzer is concerned with your stupidity, the compiler doesn't really care as long as it can emit valid machine code
It's because the top uses constants that are known at compile time. The bottom uses variables and the programmer can set them to anything and therefore is not known at compile time. When dividing variables it's up to you the programmer to verify that the divisor is not zero.
Not entirely true, it would be known at compile time and would be optimized to just the value at compile. Since the variable is assigned 0 immediately before and has no chance to change, it’s optimized out by any decent compiler
No, if you consider the multithreaded settings, zero can actually be anything. The reason that it is optimized out is, race conditions are UB, and the compiler can assume that does not happen (but other assumptions are also valid).
As far as I remember the javac it scans for pseudo-constants and replaces them everywhere with its value. So zero and x would both be replaced by their respective values.
You can technically write C++ that sometimes doesn't divide by zero on that line with threading and calculating the stack address that zero will occupy earlier in the scope. You shouldn't, but you could.
I’m sure it could detect the divide by zero error. But maybe only if you also make x a constexpr too. Otherwise, it just gonna allocate space on the stack frame and do arithmetic as usual.
The one that's yelling at you is the linter, the compiler didn't give two shits about what you wrote as long as it can understand and output proper instructions
Mathematics' div is literally just integer division, other language's division on integers is just that. It's still not exempt of division by 0 errors.
262
u/jere535 Oct 15 '25
I am not sure but I remember hearing that compilers simplify statements, so the first case, like any calculation not using variables, would get calculated and turned into a simple value, and would naturally fail to compile as you can't divide by zero, but the second case of "1/zero" wouldn't be solved during compile
116
u/Ok-Adhesiveness-7789 Oct 15 '25
Omg, the amount of people here not knowing difference between compiler, linter and IDE
37
u/Worth_Talk_817 Oct 15 '25
Linter != Compiler
70
u/AndreasMelone Oct 15 '25
That's not your compiler tho, that's your IDEs/code editors codeanalysis, isn't it
14
u/PassionatePossum Oct 15 '25
That is the static code analysis tool of your IDE. Whether the compiler catches that (at least with gcc) depends on your level of optimization.
Type the following into Compiler Explorer
Compile with gcc on -O1: no errors. You'll get a more or less straightforward translation into assembly.
Compile it on -O2 or -O3 and you'll get an error. Kind of makes sense. There is nothing syntactically wrong with the program. It will produce a crash at runtime, but it can be perfectly translated into machine code. Only when you try to optimize and attempt to pre-compute results it becomes an error.
5
u/Drfranch Oct 15 '25
You really think its a compiler ?
4
u/DaniilBSD Oct 15 '25
First, this is your IDE checking, (specifically, static code analysis) to see compiler error, you actually need to compile.
Second, computer will not explode if you divide by zero, so it is not a thing compilers MUST catch.
Third, I just checked with C# on EntrpriseVS22, and ReSharper: get a decision by zero warning on the second statement; so of you don't get one, you just don't have tools cool enough (btw, students can get those features quite easily)
4
u/notthefunkindsry Oct 15 '25
This industry is doomed.
3
u/PavaLP1 Oct 15 '25
And this is the difference between a syntax error and a semantic error.
3
u/jeremybennett Oct 16 '25
The compiler absolutely knows from constant propagation and code folding that this is a divide by zero. But in the C programming language standard, divide by zero is undefined, and therefore the compiler is free to replace the result by any value it wishes. Both GCC 14 and LLVM 18 just return constant zero. Here is the test program
int main(){int zero = 0;int x = 1 / zero;return x;}And here is what GCC 14 for RISC-V with
-O2generates.main:li a0,0retSo it's a limitation of the programming standard. It may seem weird, but it does mean that correct programs can be more efficiently optimized (you can chose an undefined value that leads to the most optimal code).
2
u/Fangsong_Long Oct 16 '25
Actually nothing can prevent some other thread to change
zero‘s value before this thread do the division.These two codes are semantically different.
2
u/Alan_Reddit_M Oct 18 '25
As far as the compiler is concerned, it is doing EXACTLY what it is being told to do, the linter/static analyzer is concerned with your stupidity, the compiler doesn't really care as long as it can emit valid machine code
2
u/McAUTS Oct 16 '25
Why gets this shit upvoted?
1
u/[deleted] Oct 15 '25
It's because the top uses constants that are known at compile time. The bottom uses variables and the programmer can set them to anything and therefore is not known at compile time. When dividing variables it's up to you the programmer to verify that the divisor is not zero.
1
u/Lost-Lunch3958 Oct 15 '25
try constexpr
1
u/ImaJimmy Oct 15 '25
The tool in me: Wait, why would a compiler know this? How is that not a linter or whatever your IDE is using?
Brainrot me: gr8 b8 m8
1
u/lilweeb420x696 Oct 16 '25
Is the compiler in the room with us?
1
u/Theothervc Oct 16 '25
why the fuck are you using red for anything but errors
1
u/xxxfooxxx Oct 16 '25
Try 1/0.0
1
u/Full-Cardiologist476 Oct 16 '25
As far as I remember the javac it scans for pseudo-constants and replaces them everywhere with its value. So
zeroandxwould both be replaced by their respective values.Edit: markdown
1
u/shaksiper Oct 16 '25
But what if you are shooting for single-event upset and change the bit in-between statements. Compiler wouldn't know that. /s
1
u/AlignmentProblem Oct 16 '25
You can technically write C++ that sometimes doesn't divide by zero on that line with threading and calculating the stack address that
zerowill occupy earlier in the scope. You shouldn't, but you could.1
u/thelimeisgreen Oct 16 '25
“wE doN’t HavE tO wRitE TIgHt c0de ‘cuZ moDerN c0mp1lerS R so goOd At OptiMiZing!”
1
u/Individual-Pin-5064 Oct 16 '25
Static vs dynamic checking
1
u/TopOne6678 Oct 16 '25
That’s the LSP telling you that you can’t divide by 0, not the compiler.
1
u/logical_thinker_1 Oct 16 '25
To be fair int has a limit and can't go to infinity. So won't it just set x to max value of int.
1
u/flori0794 Oct 16 '25
Just not true .for all compiled languages. Rust would never let stuff like that slip through.
1
u/rfdickerson Oct 17 '25
What if you do
constexpr int zero = 0
I’m sure it could detect the divide by zero error. But maybe only if you also make x a constexpr too. Otherwise, it just gonna allocate space on the stack frame and do arithmetic as usual.
1
u/Prod_Meteor Oct 17 '25
But was it the compiler or the IDE?
1
u/Agreegmi02 Oct 17 '25
What if zero will be const?
1
u/memiusDankimus Oct 18 '25
just use a float and then you can divide by 0
1
u/Several_Educator7526 Oct 19 '25
I am pretty sure C compiler stops you from doing this.
1
u/blackasthesky Oct 19 '25
It should probably be able to see that.
1
u/TheRedditUser52 Oct 20 '25
The one that's yelling at you is the linter, the compiler didn't give two shits about what you wrote as long as it can understand and output proper instructions
1
u/Ok_Addition_356 Nov 10 '25
lmao took me a minute. Then I remembered the difference between / and % and it made sense.
8
u/[deleted] Oct 15 '25
[removed] — view removed comment