void foo() {
char* a, b; // warn that b is not a pointer type as someone may expect
}
Fixes PR39150 (also I see a request for this checker on GCC Bugzilla)
Differential D52791
[Diagnostics] Check for misleading pointer declarations xbolva00 on Oct 2 2018, 10:34 AM. Authored by
Details
void foo() { char* a, b; // warn that b is not a pointer type as someone may expect } Fixes PR39150 (also I see a request for this checker on GCC Bugzilla)
Diff Detail
Event TimelineComment Actions Thanks for working on this!
Comment Actions There's a false positive. int **A, *B; // false positive: declaring a variable of type 'int *'; did you mean to declare a pointer? And IMO this should also warn: int **A, B; // no warning currently Comment Actions I think we need some documented guidelines on what is and is not an appropriate warning for Clang. I think it's reasonable to warn in cases where we are confident that the code means something other than what the programmer or a later reader is likely to expect; it's less obvious to me whether this warning fits that categorization: while a lot of people are confused by C/C++'s multi-declarator declaration rules, there are also many people who are not, and who use this kind of coding pattern (if you look at, say, the ffmpeg source code, you can find all sorts of things like this: char *p, buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 };, int *fds = NULL, fdsnum, fdsidx;, int *tmp, i, len;, int *p, vmax, v, n, i, j, k, code;, and so on). Generally in the cases where we do accept such warnings on valid code that might nonetheless mean something different from what was intended, or be misread by people who have not internalized the relevant language rules, there is a simple syntactic workaround that suppresses the diagnostic, and we suggest that workaround in a note attached to the warning. (For example, for assignment in an if condition, we suggest adding another pair of parentheses, and likewise we suggest adding parentheses for an && expression as an operand of an || expression.) Is there a similar syntactic workaround we can suggest here? For example, would int *ptr, (a), b, c; ... suppress the warning for a? Comment Actions Another possible heuristic for suppressing the check: only warn if there is whitespace before the identifier. So: int* a, b; // warning int *a, b; // no warning
Comment Actions void test(void) { int *a; int* b; } TranslationUnitDecl `-CompoundStmt <col:17, line:7:1> |-DeclStmt <line:5:5, col:11> | `-VarDecl <col:5, col:10> col:10 a 'int *' `-DeclStmt <line:6:5, col:11> `-VarDecl <col:5, col:10> col:10 b 'int *' Why not 'int*' in ast dump? Comment Actions This shouldn't be implemented here, better choice is clang-tidy. Closing this revision. |
I think this should really be off by default, this is a stylistic warning that would be really noisy for existing projects. Also, I think the text might be better spelled as "declaring a variable of type %0; did you mean to declare a pointer?". Also, -Wmisleading-declarations doesn't really describe what this warning diagnoses. This is C, so there is plenty of ways to write a misleading declaration ;). Maybe -Wmisleading-pointer-declarator?