sub-int types, casts, MISRA and RH's writings

A

Ark Khasin

MISRA came up with those "underlying types" of sub-int size (like likely
char and perhaps short) and the whole arithmetic on them.
Basically, I need to continually cast back to the "underlying" type "as
if" the computations were done on them without promotion. E.g.,
uint16_t a, b;
a = (uint16_t)(~b); //RH would not approve of it
instead of
a = ~b;
On the one hand, I find myself utterly unable to read my own
MISRA-compliant code written an hour ago.
On the other hand, there are cases where the lack of a cast does not
implement the programmer's intentions, as in
if((a^~b)==0U) ... (always false because of upper bits of ~b)
On the third hand (yes, I am a coding monkey), I could try to wrap this
ugliness in macros, like
#define COMPLEMENT16(x) ((uint16_t)(~(x)))
but it doesn't look much more readable.

I am looking for an advice on how to go about this, generic if possible.
In particular, should a MISRA-inspired company's C coding standard
adjust to the skills of the team members?
A rule like "F(x,y,2007) is always 0. Why? One, Two, Three! If you don't
know the answer, abide by MISRA Rule P.Q" sounds quite idiotic... For
the author and the maintainer may be different people.
Is there a better way?
 
B

Ben Bacarisse

Ark Khasin said:
MISRA came up with those "underlying types" of sub-int size (like
likely char and perhaps short) and the whole arithmetic on them.
Basically, I need to continually cast back to the "underlying" type
"as if" the computations were done on them without promotion. E.g.,
uint16_t a, b;
a = (uint16_t)(~b); //RH would not approve of it
instead of
a = ~b;

I can't see the difference. Surely these two are the same?
On the one hand, I find myself utterly unable to read my own
MISRA-compliant code written an hour ago.
On the other hand, there are cases where the lack of a cast does not
implement the programmer's intentions, as in
if((a^~b)==0U) ... (always false because of upper bits of ~b)

Here you either have to cast the expression or compare it to the
result you actually expect:

if ((a ^ ~b) == ~(uint16_t)-1)

another way would be

if ((a | b) == (uint16_t)-1)

both of which have the merit that the constant is probably already
named UINT16_MAX:

if ((a ^ ~b) == ~UINT16_MAX)
if ((a | b) == UINT16_MAX)

(I prefer the second.)
 
T

Thad Smith

Ark said:
MISRA came up with those "underlying types" of sub-int size (like likely
char and perhaps short) and the whole arithmetic on them.
Basically, I need to continually cast back to the "underlying" type "as
if" the computations were done on them without promotion. E.g.,
uint16_t a, b;
a = (uint16_t)(~b); //RH would not approve of it
instead of
a = ~b;
On the one hand, I find myself utterly unable to read my own
MISRA-compliant code written an hour ago.
On the other hand, there are cases where the lack of a cast does not
implement the programmer's intentions, as in
if((a^~b)==0U) ... (always false because of upper bits of ~b)

I would write
if (a == (uint16_t)~b) ...
 
E

Eric Sosman

Ark said:
MISRA came up with those "underlying types" of sub-int size (like likely
char and perhaps short) and the whole arithmetic on them.
Basically, I need to continually cast back to the "underlying" type "as
if" the computations were done on them without promotion. E.g.,
uint16_t a, b;
a = (uint16_t)(~b); //RH would not approve of it
instead of
a = ~b;

The only difference is that the first version is wordier.
Both perform the same computation. Both are vulnerable (in
theory, anyhow) to generating traps for invalid `int'
representations. One way to avoid even that vulnerability is

a = ~(unsigned int)b;
On the one hand, I find myself utterly unable to read my own
MISRA-compliant code written an hour ago.
On the other hand, there are cases where the lack of a cast does not
implement the programmer's intentions, as in
if((a^~b)==0U) ... (always false because of upper bits of ~b)

Casting seems like a good idea, but I'd also suggest
rewriting the test for clarity:

if (a == (uint16_t)~b)

or for perfect safety

if (a == (uint16_t)~(unsigned int)b)
On the third hand (yes, I am a coding monkey), I could try to wrap this
ugliness in macros, like
#define COMPLEMENT16(x) ((uint16_t)(~(x)))
but it doesn't look much more readable.

I'm not familiar with the MISRA guidelines, but it seems
to me that if they define a "whole arithmetic" for narrow types,
there may well be a standard or at least quasi-standard suite
of functions and macros to support that arithmetic. You might
want to spend some time looking for an existing wheel (doesn't
MISRA have its roots in the auto industry?) rather than spend
your effort inventing a new one.
 
O

Old Wolf

MISRA came up with those "underlying types" of sub-int size (like likely
char and perhaps short) and the whole arithmetic on them.
On the one hand, I find myself utterly unable to read my own
MISRA-compliant code written an hour ago.

I think it is better to remember "int16_t may be
smaller than int, and expressions are usually
promoted to int when used with operators", than
a whole bunch of rules about when to cast and so on.
 
A

Ark Khasin

Old said:
I think it is better to remember "int16_t may be
smaller than int, and expressions are usually
promoted to int when used with operators", than
a whole bunch of rules about when to cast and so on.
But of course it is! - for the programmer. Opinions vary on what goes
into company's coding standard, and as I am sure you know, people, even
skilled ones, forget things in the heat of coding.
 
O

Old Wolf

But of course it is! - for the programmer. Opinions vary on what goes
into company's coding standard, and as I am sure you know, people, even
skilled ones, forget things in the heat of coding.

Yes; but if they can forget about int promotion,they can surely
also forget the rule about having to place a cast in a
comparison operation.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top