Search code examples
pythoncompilationcompiler-optimization

Why Python compiler doesn't ignore syntax errors after exit()?


If you run a Python code and then call exit(), it will exit the program and the following codes won't run. But I added exit() to my program and after I had some syntax error and the program crashed. I want to know why the Python compiler didn't optimize my code before running it. I tried this issue with logical errors and it ignored them, like index out of range and so on. So why the below code doesn't work and SyntaxError happens?

print("Hi")
exit()
if 

Solution

  • It can't compile your program precisely because it's a compiler (to bytecode which it will later interpret). It doesn't stop parsing when it sees an exit(), unlike a shell reading and interpreting a shell script one line at a time. (That's not "optimization", BTW).

    Python compiles it to bytecode that calls exit if that point in the program is reached. Even unreachable code has to be syntactically valid so the whole file compiles. But since it never actually executes, it can't cause any run-time errors.

    It's not an arbitrary process. C compiler works smarter how does the C compiler can detect it?

    For example, if you run a while 1 program with C it doesn't run because of logic. but why do python doesn't do the same thing?

    That's not true.

    C compilers choke on syntax errors in unreachable blocks, like int foo(){ if(0) if if; }. Also, while 1 isn't valid C syntax.

    https://godbolt.org/z/cP83Y866b. Only #if 0 preprocessor stuff, or comments, can hide stuff from the compiler so it doesn't have to be valid syntax and grammar.

    Syntax and grammar need to be valid in the whole file for it to parse into something to compiler can compile.

    In C and C++, unreachable code (that isn't commented out) even has to be valid in terms of types matching, e.g. T x = y; won't compile if T is int but y's type is char*. That would be syntactically valid but "ill-formed". Per cppreference: Outside a template, a discarded statement is fully checked. if constexpr is not a substitute for the #if preprocessing directive

    But inside a template, it can, for example hide stuff. https://godbolt.org/z/frTcbMb3T

    template <typename T>  // being a template function makes if constexpr special
    void foo(int x) {
      if constexpr (false) {
          int x = "hi";    // ill-formed, type mismatch.  But still valid *syntax*
      }
    
    #if 1           // 0 would truly ignore all text until the closing #endif
      if constexpr (false) {
    //      int x = = 2;  // syntax error if uncommented
      }
    #endif
    }