/edit: had that mixed up in my head. Interestingly, clang does warn about the overflow:
main.c:6:17: warning: implicit conversion from 'int'
to 'int16_t' (aka 'short') changes value from
65536 to 0 [-Wconstant-conversion]
int16_t s16 = 65536; -2^16 = (-2) ^ 16 = 0b111...1110 ^ 0b10000 = 0b111...11011110 = -18
if I'm not mistaken.But since philosophically a signed int has '1's in every bit from the MSB to infinity towards the left, it should thus be -0 not 0.
I code in C/C++ too, although not exclusively. I facepalmed a few seconds later, but it goes to show the value of having this be a compiler warning.
Does depend on what kind of lint you want to catch but something like this 'just' needs some lexing and parsing to give a usable AST that's reasonably clean so it's not too hard to write lint rules against it. (Not trivial for C & C++ hence 'just')
Building the full compiler is much more work, especially if you want a decent optimizing compiler.
In fact most of the essential complexity is in the front end; you make do with a simple back end, but the front end is irreducibly complex if you want it to actually compile the language to spec.
And you need the front end to lint, especially if you want to avoid false positives, the bane of linting tools.
[1] http://blog.reverberate.org/2013/08/parsing-c-is-literally-u...
A test passing just means that the code and the test agree, not necessarily that both are correct.
I'm pretty sure Dennis Ritchie at some point himself said that not including a linter was a mistake, but I cannot find a quote of this with a quick search.
In defense: configuring a package that is compiled by lots of people on lots of machines with lots of versions of various compilers requires a lot of attention to warning flags and such. If you aren't starting out a package from a blank buffer it's very hard to get this right.
But I am frequently shocked by the number of compiler warnings I get from code downloaded from public repos and compiled in precisely the environments it's been documented to have been tested on.
"To encourage people to pay more attention to the official language rules, to detect legal but suspicious constructions, and to help find interface mismatches undetectable with simple mechanisms for separate compilation, Steve Johnson adapted his pcc compiler to produce lint [Johnson 79b], which scanned a set of files and remarked on dubious constructions."
Some may even have released code that still has these time bombs waiting to occur.
Every external tool is a lost opportunity for quality enforcement.
https://docs.microsoft.com/en-us/visualstudio/code-quality/u...
Just making the point that they have been largely ignored.
Ever heard of PC Lint from Gimpel? It was my first one.
Or do you think I would be critic of how many use C, without adopting best practices myself?
One learns a lot about code quality, or lack thereof, when doing enterprise consulting.
Pure truth, there. One has seen neither really awful code nor really great code until they have seen the wide array of code quality produced by an enterprise with a few decades of software development history. Any enterprise will suffice, it doesn't have to be a huge corporate entity.
There are a very few developers who are really good and who really care, and there are very few who really do not care and who are really not good, and most are somewhere in between.
Check "Which of the following tools do you or your team use for guideline enforcement or other code quality/analysis?" results.
Upon first reading, I'd assume they are seeing the maximum unsigned values, but their variables aren't declared as unsigned -- and C/C++ default to signed values. Secondly, representing the nth power of two actually takes n+1 binary digits, so e.g. 28 is a one, followed by 8 zeros -- overflowing any 8-bit variable, signed or unsigned! This is undefined behavior as-declared (signed values), but would be entered as a zero for explicitly declared unsigned variables.
Personally, if I were to be implementing this, I'd use bitwise operations to generate the correct values, and explicitly acknowledge in a comment something like "the following code knowingly breaks the abstraction of numeric values. It is likely not portable to other hardware, nor should you assume easy extension to other variable types. Das Quellcode ist nicht fur der gefingerpoken!"
A rather unfortunate operator choice on the part of C: open to confusion and precluded adding ^ as an exponentiation operator to the language.