
Inline adoc files when they are included exactly once. Also fix language tags because this inlining gives us better information on what language the code is written in.
81 lines
2.8 KiB
Plaintext
81 lines
2.8 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Casting an object pointer can very easily lead to undefined behavior. Only a few cases are supported, for instance casting an object pointer to a large enough integral type (and back again), casting an object pointer to a pointer to void (and back again)... Using a pointer cast to access an object as if it was of another type than its real type is not supported in general.
|
|
|
|
|
|
This rule detects casts between object pointers and incompatible types.
|
|
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,cpp]
|
|
----
|
|
struct S1 *p1;
|
|
struct S2;
|
|
void f ()
|
|
{
|
|
(float) p1; // Noncompliant, conversion to floating point type
|
|
(int *) p1; // Noncompliant
|
|
float f;
|
|
int *i = (int *)&f; // Noncompliant, undefined behavior even if sizeof(int) == sizeof(float)
|
|
(int) p1; // Compliant, but might be undefined behavior if 'int' is not large enough to hold the value of p1.
|
|
(void *) p1; // Compliant, conversion to 'void *'
|
|
(struct S2 *)p1; // Noncompliant, conversion to another type.
|
|
}
|
|
----
|
|
|
|
|
|
=== Exceptions
|
|
|
|
In C, it is allowed to cast an object pointer to a character pointer to access the byte representation of the object. This rule ignores this case.
|
|
|
|
Anything can be safely cast to ``++void++`` (since nothing can be done with a result of this cast), and doing so is a common pattern to silence compiler warnings about unused variables. This rule ignores such casts.
|
|
|
|
[source,cpp]
|
|
----
|
|
void f(int *p) {
|
|
(void)p;
|
|
}
|
|
----
|
|
|
|
|
|
== Resources
|
|
|
|
* MISRA C:2004, 11.2 - Conversions shall not be performed between a pointer to object and any type other than an integral type, another pointer to object type or a pointer to void.
|
|
* MISRA C:2012, 11.3 - A cast shall not be performed between a pointer to object type and a pointer to a different object type.
|
|
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
Remove this hazardous cast.
|
|
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
=== relates to: S1944
|
|
|
|
=== is related to: S855
|
|
|
|
=== is related to: S860
|
|
|
|
=== on 23 Oct 2014, 15:09:10 Ann Campbell wrote:
|
|
\[~samuel.mercier] might this be a "bug"?
|
|
|
|
=== on 23 Oct 2014, 16:12:52 Samuel Mercier wrote:
|
|
\[~ann.campbell.2] I will flag it as a bug. Anyway the cases allowed by this rule seems also buggy:
|
|
|
|
* Conversion between pointers and integral types can result in loss of bits depending on the target architecture and the chose integral type. Also manipulating a pointer as integer is probably meaningless.
|
|
* Conversion between pointers to objects requires the objects to have a common part (which is unmaintainable) and should be avoided.
|
|
* Conversion to ``++void *++`` loses the information of the underlying type, so apart for calling free or realloc I don't see the point. But for this particular cases the conversion is implicit and does not requires a cast.
|
|
so this rule seems odd to me...
|
|
|
|
endif::env-github,rspecator-view[]
|