It’s hard work printing nothing
tedunangst.com
tedunangst.com
Think about how you're supposed to treat compiler warnings: You don't ignore them--they are there for a reason. Quite the opposite--you should use your compiler to treat warnings as errors, enforcing good development practice from the start.
The grandparent's comment was about the surprise and concern you feel when you see all of these warnings yet things still evidently "work". When I sit down to a new project, pull down the latest code, start to work with it and see thousands of compile-time and run-time warning messages, the alarm bells start going off in my brain: This project is barely held together.
GTK can't control yet alone offer patches for the 1 million + programs that depend upon it as a library.
I get some compiler warnings when I compile SQLite. Isn't this a problem?
Doesn't it indicate poor code quality?
Quality assurance in SQLite is done using full-coverage testing, not by
compiler warnings or other static code analysis tools. In other words, we
verify that SQLite actually gets the correct answer, not that it merely
satisfies stylistic constraints. Most of the SQLite code base is devoted
purely to testing. The SQLite test suite runs tens of thousands of separate
test cases and many of those test cases are parameterized so that hundreds
of millions of tests involving billions of SQL statements are run and
evaluated for correctness prior to every release. The developers use code
coverage tools to verify that all paths through the code are tested.
Whenever a bug is found in SQLite, new test cases are written to exhibit
the bug so that the bug cannot recur undetected in the future.
During testing, the SQLite library is compiled with special instrumentation
that allows the test scripts to simulate a wide variety of failures in
order to verify that SQLite recovers correctly. Memory allocation is
carefully tracked and no memory leaks occur, even following memory
allocation failures. A custom VFS layer is used to simulate operating
system crashes and power failures in order to ensure that transactions are
atomic across these events. A mechanism for deliberately injecting I/O
errors shows that SQLite is resilient to such malfunctions. (As an
experiment, try inducing these kinds of errors on other SQL database
engines and see what happens!)
We also run SQLite using Valgrind on Linux and verify that it detects no
problems.
Some people say that we should eliminate all warnings because benign
warnings mask real warnings that might arise in future changes. This is
true enough. But in reply, the developers observe that all warnings have
already been fixed in the builds used for SQLite development (various
versions of GCC, MSVC, and clang). Compiler warnings usually only arise
from compilers or compile-time options that the SQLite developers do not
use themselves.
https://www.sqlite.org/faq.html#q17Also: "The highest level of testing was performed with a high fidelity digital simulation of the computer, spacecraft hardware, and mission environment."
For me, my phone is mission critical.
Whether or not this is acceptable for software and hardware to have gotten this unreliable is another question entirely.
This is a better read than the linked article, really.
The reason Firefox pulls libtiff is simply because it uses a generic image manipulation library (libgdk-pixbuf), which in my system it's also used by many other applications - which do require TIFF support. I guess if you have a desktop with only FF installed that may be a waste, but how many people really have FF and not any kind of image viewer installed?
What software? And what does it use it for?
I don't see the difference. Instead of including a specific compiler for their needs, they are bazaar-ing a full generic C compiler (along with irrelevant libraries) just like Mozilla is doing with a generic image manipulation library, which pulls libtiff since many packages that also use it need TIFF support.
A Generation Lost in the Bazaar (2012)
There's an argument, but it's a really lousy one. If you're passing NULL as a string to printf, your code is broken. A crash which results in someone tracking down and fixing the bug is far better than quietly doing something which is 100% guaranteed to be wrong.
Rule of Repair: Repair what you can — but when you must fail, fail noisily and as soon as possible.
To take this example to the extreme, imagine if the default state of the runtime/OS were configured so that invalid memory accesses didn't cause segfaults, but e.g. yielded -1 or 0 or some other value and simply let the code continue... by the time you see something wrong, it's probably very far away from what originally caused it.
It's funny to see OpenBSD's printf doing this explicit null-checking and that they are considering to remove it, when AFAIK Microsoft's C library printf has always done the IMHO sane thing of just reading and writing to whatever addresses it's been given --- and if they turn out to be invalid, like null, then it crashes as it should.
Not necessarily. Wrong is relative and can have either small or large costs, and crashing also has a cost to the user (and to the developers if they lose users.)
As an example, I play a very old video game (Descent). One of the major problems with one of the modern source ports is that the game crashed under certain conditions -- like if it received a malformed data packet. This is a game that's already fairly tolerant to lost data, so just dropping a bad packet is an acceptable result. By comparison, crashing in the middle of a competitive match is a much worse result, because it affects things like momentum and where various powerups have been left around the map.
It would be great to fix the bug that was resulting in malformed packets -- but the cost of directly affecting a high-stakes match is not worth it. I'd rather tolerate a fraction of a percent of lost data every game for the next 20 years than ever have a high-stakes match where the result was tainted by a badly-timed crash.
In practice this means that during development you want the game to fail fast and loudly so that the biggest bugs are taken care of, but gradually add features to fail more quietly later, e.g. by moving more errors into logs and traces.
Sure, the player's software on the other end should not have sent the malformed packet, but crashing on bad untrusted input is a bug of its own, and I'd say a worse one.
(And who knows, maybe the malformed packet wasn't caused by a bug on the other side, but by something malicious, or perhaps some sort of network-caused data corruption.)
The overall point here is that there is a real cost to making your software crash. Most of your users want software that is stable, and crashing is often worse than doing the wrong thing and continuing to run in a slightly janky state.
And often competitive players form groups to play in, so everybody knows each other even while practicing.
You'd probably want to be on a LAN to minimize the risk of this happening accidentally.
So in practice, I don't think it would matter too much even if money was on the line. You would just have to take appropriate precautions, and watch to disqualify people for cheating.
Except that it's also possible to gain an advantage by causing a game crash.
Ultimately, "crash the game" is among the worst possible options. (Also ultimately, it's a very old open-source game in which it's relatively easy to compile your own client software, so "make the game crash as an anti-cheat method" only works on honest players anyway.)
That's incredible. I've worked on some very large python projects before, but 200? That's pure insanity. Can I ask what that project does? I just can't imagine a project where you'd need 200 libraries.
% pip freeze
Django==1.10
That's after a pip install in a fresh virtual environment.For example, my project has 66 dependencies after cleaning up pip-freezes' output to only keep secondary dependencies if they were depended on by more than one thing (e.g. chardet is a dependency of every package that works with character processing).
If we're talking about only primary dependencies, we have 13 or so.
If we're talking about the entire dependency network... its easily above 200.
Though, if 200+ packages were used in the codebase explicitly, that requires some sort of wizardry!
And also various development or test packages installed in the venv at the time e.g. third-party debuggers, profilers, etc...
Maybe this needs printf for a test suite, and talloc doesn't call it itself? Maybe there is also a way to run talloc in some verbose mode? I'm not familiar with it.
There are two types of "low-level programmers" I've encountered: there those who truly "think low-level" and enjoy it, the ones who will avoid huge amounts of abstraction and general inefficiency in favour of small, efficient and usually very simple solutions; and those who may be using a low-level language, but are actually using it from the mindset of someone who loves abstraction and libraries more than anything else. I'm in the former group.