How to get clang to warn about very simple narrowing
Asked Answered
R

1

6

If I am using clang tools, what is the recommended way to get clang or some part of the clang toolchain to tell me that e.g. passing an int to a function that takes a short might be a bad idea?
Given this very simple program

static short sus = 0;
void foo(short us) {
  sus = us;
}

int main() {
  int i = 500000;
  foo(i);   // any indication from clang this might be a bad idea
  return 0;
}

I must be missing something very simple here, right?

Rains answered 12/10, 2021 at 23:20 Comment(10)
To clarify, you want to do this without changing the source code in any way, correct?Fruitless
@Fruitless this is not a question about improving the code in the example, it is about how to get clang or a tool in the clang toolchain to indicate what is clearly a problematic practice (although allowed by the standard) in this example namely passing an int to a function that takes at shortRains
Ok, that's perfectly valid. I was just checking, since there might be techniques that change source code in a way that allow you to preserve the same behavior, while also getting the warning you want.Fruitless
"-Wall" is far from all, and even "-Wextra" only covers just a fraction of what your compiler can do for you. Get that manual, chapter "Warning Options", and be amazed...Ammonium
@DevSolar: Unfortunately that section of the clang manual lists all the options, but doesn't explain what they actually do: clang.llvm.org/docs/DiagnosticsReference.html#introductionPhototonus
@NateEldredge: It gives the warning text to each, which should be enough really. And you can always cross-check with the GCC manual, which has mostly the same warnings, and with some added explanation. {shrug}Ammonium
@DevSolar: Perhaps. In this case it's not very useful unless you knew that the technical term for this language feature was "implicit conversion". And it so happens that GCC does not support this warning at all (it's a clang addition), so the GCC manual is no help. Of course RTFM is good advice in general, but it doesn't help much for this question.Phototonus
Fair point @DevSolar, I have it bookmarked although amazed can be similar to overwhelmed, for some reason I was mistakenly focused on searching for the word narrowing.Rains
@NateEldredge: I wasn't trying to answer this question, I wanted to point out that getting the most help out of your compiler requires digging through the warning options on a regular basis, at the very least every major release. As for GCC, -Wconversion will bring up the equivalent warning.Ammonium
@Ammonium if you're curious my solution (which if for a huge legacy body of code, not the toy example posted here) was to go with the broader family of warnings -WimplicitRains
P
13

The -Weverything option is useful in situations like this. It enables every warning option that clang has, including many that -Wall -Wextra doesn't include. Many of them are useless or counterproductive, but if there is one that warns on the code you consider problematic, this will let you find it, and tell you which option would enable it specifically. Try it on godbolt.

In this case, using -Weverything shows us:

<source>:8:7: warning: implicit conversion loses integer precision: 'int' to 'short' [-Wimplicit-int-conversion]
  foo(i);   // any indication from clang this might be a bad idea
  ~~~ ^

So the option you want is -Wimplicit-int-conversion.

Phototonus answered 13/10, 2021 at 0:10 Comment(4)
Teach how to fish, instead of giving a fish. Very nice :)Fruitless
Thanks @Nate Eldredge, this answer is perfect for including the technique of "casting the biggest net" first to find any specific warning. Naturally I'm surprised an implicit conversion is not in -Wall nor Wextra. It is something that can be hard to spot in thousands of lines of inherited code, can cause a nasty bug and has at least one obvious solution (cast at invocation) to make it explicit.Rains
@Chip: You have to realize what "all" and "extra" means, historically. The "all" refers to "the warnings that all the developers could agree on", and "extra" meant "some additional ones that probably will not cause problems with legacy code" (I had a quotation on that from the GCC docs at some point but cannot find it ATM...). At no time did "all, extra" mean "be extra sringent with your warnings". (That would be clang's -Weverything, it srems.)Ammonium
Despite the question being about clang++ specifically, it would be interesting to see what the corresponding g++ flag would be, for reference.Aquamanile

© 2022 - 2024 — McMap. All rights reserved.