Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Compiler Warnings for Dangerous Casts

With all C compilers that I'm aware of, -Wall warns about implicit casts but never warns about any explicit casts. I've been trying to find a flag (doesn't matter if it's for gcc, clang, any c compiler will do) that will cause a warning to be emitted when there is a cast that results in undefined or implementation-defined behavior. Here's an example illustrating where I would and wouldn't expect a warning:

#include <math.h>

struct person {
  int tag;
  char* name;
};

int foo(struct person* p) {
  int* tagPtr = (int*)p; // this cast is fine, cast to first member ptr is allowed
  double* badPtr = (double*)p; // this cast should cause warning
  return ((*tagPtr) + (int)(round(*badPtr)));
}

The cast to a an int* is well defined, and the cast to double* is not, but gcc does not warn me about this second cast. Is there a way to get it to do so? Or does another compiler or even a linter provide this feature?

And then there's the area in between "definitely well defined" and "definitely implementation defined" which is "could be well defined depending on context". For example, casting from a int* to a struct person* is well defined if the int* was originally formed by a cast in the other direction (implied by section 6.7.2.1p15 of C spec). The provenance of a pointer is seldom available, so a compiler or linter would not known if this cast was sound or unsound, only that it is possible that it is sound. To be useful to me, the warn-on-dangerous-cast feature would need to not warn in this situation, only in situations where the cast is guaranteed to be implementation-defined behavior.

Is there a tool that can help with this?

For context, I'm working on using C as a target for a language with tagged variants. If the variants have different sizes, casting is essential. It would be nice, however, if the compiler could help-spot check my generated code by making sure I don't do any nonsense casts. I suspect that optimizing compilers should have the information to provide this warning since this is the same information that would be needed for alias analysis. I've just not been able to figure out if any compiler bends the information to this end.

like image 419
Andrew Thaddeus Martin Avatar asked Nov 07 '22 00:11

Andrew Thaddeus Martin


1 Answers

Is there a tool that can help with this?

Yes: The clang-cl compiler that you can (optionally) install and use in Visual Studio 2019. I copy/pasted your code without change into my VS IDE and this was clang's response:

warning : cast from 'struct person *' to 'double *' increases required alignment from 4 to 8 [-Wcast-align]

Running a (static) code analysis added this:

warning GCC3CDF22: cast from 'struct person *' to 'double *' increases required alignment from 4 to 8 [clang-diagnostic-cast-align]

like image 74
Adrian Mole Avatar answered Nov 12 '22 20:11

Adrian Mole