As I have discussed on a previous blog post, static typing helps on correctness by providing well-typed programs through type checking algorithms. Compiler warning messages and compiler error messages are not thrown as they were made by a capricious developer. Almost all of them are following a language definition, and they help if you want to build better programs. The more strict are your compiler flags, better are your programs. Using language extensions, which are not present on their standard definitions is not so cool as it seems. That depends on the language, sometimes there is very long time after certain language extensions are passed to the language definition. So, you should try to look on how can you write better code for that language without abusing of its extensions and extra features provided by the compiler.
Almost every compiler or language interpreter has warning and error flags that can help you to write better code. On my case, I use the flags “-Wall -Wextra -Wshadow -pedantic -std=c99” with gcc(1) and “-Wall -Wextra -Wshadow -pedantic -std=c++98” with g++(1). That allows me to write better source, which can be compiled by different versions of the same compiler, and that source code is easier to be migrated to other platforms, because it is not abusing of some nifty gcc(1) extensions. The same strictness is applied to other languages. I compile Haskell source code using the flags “-Wall -Werror” with ghc(1). I think that you have similar options in your compiler, and what those compiler flags on my examples are doing is pretty clear — if you have deep programming practices.
The same applies to language interpreters. I recall my Perl scripts starting with the “-W” and the “use strict” directives. So, compiler flags can help you to write better code, but sometimes compiler flags are not enough to build better programs. You can use third party tools that can help you too. Most compiler flags enabling strict checks are making your code use a better approach on its type checker and language constructs, but there are some third party tools that will allow you to check your source code for common mistakes and flaws. That is the case of static analyzers, metric tools and style checkers. Each tool will bring you a better idea about how your code can meet correctness through a type checker and similar semantic analysis. Strict language semantics will lead you to better scopes of your program goals. For example if you are working on a Python 2.X project, that will be ported to Python 3.X, you can use the “-3” flag to warn you about incompatibilities with Python 3.X. Start reviewing your compiler flags, playing a little with them, learning on how your compiler can enhance your programming practices.
Correctness can be easily reached if you can use strict semantics of your favorite programming language. For example if you are using Python as a programming language, you can use some static analyzers like pylint, pycheckers, pep8 and pyflakes, among other tools. If you can pick all those warnings thrown by that kind of tools and your compiler flags, you will be writing better code.