4 ms·
> Unfortunately, this size_t is also passed to functions whose size argument is an int (a signed 32-bit integer), not a size_t. Is this the type of things that
by Zababa 5y ago
> Unfortunately, this size_t is also passed to functions whose size argument is an int (a signed 32-bit integer), not a size_t.
Is this the type of things that could be caught by a linter or strict compilation rules? This seems to be to be a failure of the type system.
- gruez 5y agoAFAIK most compilers by default will output a warning in this case.
- jeffbee 5y agoI don't see any warnings for this narrowing parameter conversion. #include "stddef.h" short foo(short a) { return a % 42; } size_t bar(void) { size_t sz = ~0UL; return foo(sz); } https://godbolt.org/z/3ec9v8Pa4 https://godbolt.org/z/3ec9v8Pa4
- xeeeeeeeeeeenu 5y agoIt warns if you add -Wconversion. Unfortunately, that flag generates lots of false positives (at least in gcc), so using it isn't always a good idea.
- jeffbee 5y agoIt isn't ever a good idea. C programmers are just supposed to know about the conversion and promotion rules, every time they add a line, even though the rules are actually insanely complicated. Compiler warnings can't overcome this because programmers have no way of just discovering one of GCC's 726 warning flags, only a few of which are enabled by -Wall and -Wextra, most of which are way too noisy to serve a useful purpose.
- morio 5y agoWhat kind of false positives are you seeing with gcc? Personally I have never seen gcc spitting out a false positive. IMO it's always a good idea to explicitly downcast even if you know that it's 'safe'. That way someone else will see instantly what's going on. The fact that Rust requires it should tell us something.
- xeeeeeeeeeeenu 5y agoFor example, I've just reported this: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101537 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101537 You can find more cases in the bugtracker. To be fair, it seems many of them were fixed in recent releases.
- Cloudef 5y agoThe 1 and 0 are ints. It most likely complaints because the sign isn't same.
- ototot 5y agoIn my own small projects, I always add -Wconversion to build configuration. I think the false positive is affordable when you start from small piece of code.
- saurik 5y agoYeah; AFAIK you need something like clang-tidy's cppcoreguidelines-narrowing-conversions check (which everyone should definitely be using). (edit: But I'm wrong! That check is apparently similar to the -Wconversion mentioned by someone else.)
- gruez 5y agoOn MSVC, default project settings I get: warning C4267: 'argument': conversion from 'size_t' to 'short', possible loss of data https://godbolt.org/z/nYeWT7zv6 https://godbolt.org/z/nYeWT7zv6 (/W3 is the default warning level when creating a new project) I saw these warnings so often that I assumed that every compiler had them.
- im3w1l 5y agoToo bad that most projects are so full of integer size and signedness warnings that people get warning fatigue and just completely ignore them.
- loeg 5y agoGCC and Clang (the predominant Linux and Mac compilers) mostly don’t warn by default, you need -Wall or other flags (-Wextra, -Weverything, or specific flags like -Wconversion).
- nly 5y agoThey can't warn by default, because on some platforms long->int isnt a narrowing conversion.
- aaronmdjones 5y agoThe compiler knows what platform it's compiling the code for, though.
- usefulcat 5y agoGCC's -Wconversion has some issues. For example, good luck getting gcc to /not/ emit a warning for this code, in C or C++. I have yet to find the appropriate cast to avoid a warning. Clang does not warn for this. typedef struct { unsigned value : 4; } S; void foo(S* s, unsigned value) { // error: conversion from 'unsigned int' to 'unsigned char:4' may change value s->value = value; } I mean, I guess I can see the rationale.. it's just annoying to have to resort to using pragmas to turn off -Wconversion whenever I need to assign to a bitfield.
- Denvercoder9 5y agoDoes it still warn if you do `s->value = value & 0x0F`? That seems like a reasonable alternative to pragmas if it works.
- ainar-g 5y agoAt this point, you can—and probably should—consider C and “C-with-analysers” two different languages. If you use static (and dynamic, if you have tests) code analysis, making software without these issues is way easier, and doing so without these tools is essentially impossible. Both because of the C language itself as well as because of the culture of “bytes go brrr” and “just use a debugger” that a lot of middle-level C programmers have in my experience.
- kllrnohj 5y agoYes, it is the type of thing caught by a linter or strict compilation rules. https://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.html https://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidel... But strict compilation rules (eg, clang's -Weverything) mainly only work if you treat them as errors (so -Werror), and then some of those strict are then also questionable at best, and just outright annoyingly wrong at worst. For example, unused parameter warnings on virtual methods are a waste of time to deal with. It's not a symptom of a bug most of the time, so it being an error just generates workaround churn or you end up just disabling the warning and then maybe that bites you the few times it would have pointed out an actual issue. Beyond the blanket ones like clang's -Weverything, it can otherwise be a job to keep up with compiler upgrades and the vast number of warning options they have.
- heavenlyblue 5y ago> For example, unused parameter warnings on virtual methods are a waste of time to deal with. Why is that even a warning? If at least one of the implementers use a parameter and a warning is shown the warning itself is wrong. That’s just broken implementation of the warning?
- codedokode 5y agoYes, this can be caught by a static analyzer and it is sad that Linux doesn't use it. I wonder, is it because the code quality is low and there would be too many warnings?
- SolarNet 5y agoThey do use them, but only in a narrow fashion. A lot of people have tried to make default kernel wide static analyzers but they are mostly not useful. And it's because the kernel does a lot of non-standard things, mostly because it has to. It is not a normal program.
- gaul 5y agoclang's -Wshorten-64-to-32 can catch this: https://clang.llvm.org/docs/DiagnosticsReference.html#wshorten-64-to-32 https://clang.llvm.org/docs/DiagnosticsReference.html#wshort... The more general-purpose -Wconversion has many false positives, often around int to char conversion. Some functions like int toupper(int) have an unexpected int return type to deal with special out-of-bound values like EOF.