5 ms·
Warnings and static analysis tools are good, but wrangling them across multiple tools, architectures, and coding standards is hard. Really hard. Different compi
by planteen 10y ago
Warnings and static analysis tools are good, but wrangling them across multiple tools, architectures, and coding standards is hard. Really hard. Different compilers will throw warnings for different things. Linting gets crazy. A customer might ask you to run your code against a MISRA ruleset. A different customer may have their own coding standard. The two standards may contradict each other in areas.
Did you know that printf returns a value? Aggressive linting tools will throw a warning about an unchecked return value.
So is printf("hello world?\n") wrong? And (void)printf("hello world\n") right? I don't know anymore.
- ktRolster 10y ago>And (void)printf("hello world\n") right? then of course, you find a tool that complains, "useless cast"
- planteen 10y agoYep!
- thr0w__4w4y 10y agoSerious question (I've been exactly the guy that planteen described -- wrangling code into submission for multiple static analysis tools and compilers, for warnings, MISRA compliance, etc.) So my question: do you remember what tool would complain about such a construct (e.g. casting return value of printf() to void)? Reason I ask is because printf() returns a value; the cast to void is explicitly and deliberately -- right or wrong -- saying, "It's OK, I got this. I am choosing to ignore it." So a static analysis tool complaining about such a construct strikes me as a bit odd.
- RealityVoid 10y agoWell, hello there, fellow MISRA warning wrangler! I think you're right and I usually find MISRA gives decent warnings and solving the warnings is quite instructive. I remember, for example, John Carmack had nice things to say about static code analysis.
- wahern 10y agoGCC's warn_unused_result function attribute still warns even if you cast to void. And that's unlikely to change. Here's the lastest thread on that. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 Older version of glibc tagged printf, etc, with warn_unused_result and it was extremely annoying. The defense was understandable but that it was eventually removed was the right decision. There are a couple of other warnings I always explicitly disable, including -Wmissing-field-initializers and -Winitializer-overrides/-Woverride-init (clang/GCC). I always use -Wall. I'd like to use -Wextra but it's problematic given that every few releases someone may introduce a new diagnostic that emits spurious warnings. When a nice clean build suddenly starts spitting out warnings you get a deluge of complaints and pointless patches at exactly the moment you have zero time to deal with them. So I usually stick to just -Wall and then run separate static analyzers (including clang static analyzer) before a release. It doesn't help that with clang you now have twice the problems, and often twice the number of workarounds required. Notice above that disabling initializer override warnings requires a different option on clang than GCC. And while with recent versions of GCC and clang you can disable certain warnings using pragmas, you still need to special case each compiler #if __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-field-initializers" #pragma clang diagnostic ignored "-Winitializer-overrides" #elif GNUC_PREREQ(4,6,0) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmissing-field-initializers" #pragma GCC diagnostic ignored "-Woverride-init" #endif So much useless boilerplate.... And then there are the people who build your software with -Wextra regardless and complain when they get spurious diagnostics. IIRC, GCC only enables -Woverride-init with -Wextra whereas clang enables the similar check with -Wall. I explicitly disable it for GCC precisely because invariably people will try to compile stuff with -Wextra. Given how much larger C++ is than C, I can only imagine C++ developers have (or will have in the future) many more headaches of this kind. (But not with initializer overrides specifically as C++ rejected named initializers, which is the only way to override initializers. It's one of the ways that C and C++ have irreversibly split.)
- pjmlp 10y agoWhich is why I tend to support languages with stronger type safety, although I also enjoy C++ a lot. Type systems are not optional and are the same regardless of the compiler, vendor, customer or willingness to use them.
- a_t48 10y agoYour logging code should be wrapped up in a helper anyhow, so you can easily filter or send it to disk\network.