Maybe it's just me having a weird day, but I have a few questions on Clang warnings that need a short example.
Suppose for a while to have a piece of code like this
/// \file unsafe.c
#include <stddef.h>
static int goo (int * pi, size_t a)
{
return pi[a];
}
int main (int argc, char *argv[])
{
(void)argc;
(void)argv;
int goz[4] = { 0, };
return goo(goz, 0);
}
Then you go with Clang as follows
# clang --version
clang version 16.0.3
Target: i686-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files (x86)\LLVM\bin
# clang -std=c11 -Weverything unsafe.c -o unsafe.exe
unsafe.c:4:24: warning: 'pi' is an unsafe pointer used for buffer access
[-Wunsafe-buffer-usage]
static int goo (int * pi, size_t a)
~~~~~~^~
unsafe.c:6:12: note: used in buffer access here
return pi[a];
^~
unsafe.c:13:13: warning: mixing declarations and code is incompatible with
standards before C99 [-Wdeclaration-after-statement]
int goz[4] = { 0, };
^
2 warnings generated.
There's an unsafe pointer. I do agree that function
goo()has no means, with a generic pointer, to know whether an index applied to it (an arithmetic expression) is safe. Note that's not because I did not check it for NULL - I just didn't to maintain the example short.
I can't think of a safe pointer, to an arbitrary-sized vector in C, that I can pass to a function that retrieves an indexed element - maybe because I'm on a weird day
What would be a good solution for Clang's sake?Mixing declarations and code is incompatible with standards before C99. That's cool. Here's why I asked on command-line invocation for C11 ...
Why has it been blatantly ignored? (My weird day, I know)
EDIT: I added the #include <stddef.h>, as it was missing. Now that's curious: this wasn't spotted by Clang.
if (a < 4) return pi[a]; else return 0;ora < nwherenis an additional passed parameter, does not resolve the warning. So there is a question of what sort of test or other code Clang expects there. For the second issue, there is no conflict between compiling using a C 2011 interpretation of the standard but warning about issues that may arise for other versions of the language. That’s a compiler designer choice about how useful the warning is. And it is not a default warning but one that is requested (by-Weverything).-Weverything, but also C11: I don't think it makes sense to show warnings about a previous standard. Just think what a mess would be compiling for the next C23 features and still have all the warnings on how C99 disagrees...int main(void)would have reduced some noise in the example.-Weverythingis purposefully noisy; it includes lots of warnings that are not expected to be useful in routine work. They are for people who are scouring for the code and hence do include warnings that may affect portability to previous versions of the standard. For routine work, use-Wall.ptr[size]parameter. I see this newer approach more useful, even if it is non-traditional.