1

I have a C codes in my project. In some part of the codes I have used conversion from int8_t to int32_t conversion directly and made a Polyspace analysis.

In polyspace analysis, it says that this is prone to error and I need to convert first to char than to int32_t. I did not understand well why this is needed.

Also I have seen similar expression in link below which says:

Signed character data must be converted to unsigned char before being assigned or converted to a larger signed type. This rule applies to both signed char and (plain) char characters on implementations where char is defined to have the same range, representation, and behaviors as signed char. Source website

I have tried same conversion on my PC with Dev-C

My code is:

#include <stdio.h>
#include <stdint.h>
void main(void)
{
    int8_t b = -3;
    int32_t b_32 = (int32_t) b;
    printf("%d \n",b);
    printf("%d \n",b_32);
}

And output seems no problem exists:

-3

-3

Process exited after 0.0807 seconds with return value 4 Press any key to continue . . .

So, I see here no problem. Why conversion to char is needed?

Thanks.

  • `int8_t` is a type for representing 8-bit signed integer, not "characters". – KamilCuk Mar 03 '21 at 13:08
  • 4
    Have you tried changing your main function signature to return `int` instead of `void`? The exit code of 4 may have something to do with the signature; see [What should main() return in C and C++?](https://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c). – Alex Riveron Mar 03 '21 at 13:12
  • Thanks for that, but actually my question resolves around data type connection. But thanks anyway. – Yusuf Selim KARATAS Mar 03 '21 at 13:43
  • Your example code exactly demonstrates the problem when you recognize that the issue is that the software in question wants to see value 253 when your `b` has value -3. – John Bollinger Mar 03 '21 at 13:53
  • 1
    I tried your code with Polyspace Bug Finder and Polyspace Code Prover R2021a, with the MISRA-C:2012 and CERT-C coding rules checkers activated but the tool does not raise a problem. It would be useful to know where exactly do you see the problem. – Alex Deba Mar 14 '21 at 16:29
  • @AlexDeba Hi Alex, this is the sample code. Actually I have not tested this code part in Polyspace. But I am suprised that it did not give any error. Also I do not think that is may be the source of the difference but I have run Polyspace 18b. That may be the source of the problem. But I am not sure. – Yusuf Selim KARATAS Mar 14 '21 at 17:07
  • @YusufSelimKARATAS I have tried 18b as well, with both Bug Finder and Code Prover but no problem raised by the tool on your code sample. – Alex Deba Mar 15 '21 at 08:30

2 Answers2

1

When they say "character data," they mean text. Text characters cannot be negative, so they are giving tips on ensuring that codes in e.g. ISO 8859 format will stay in the 0-255 range.

Since you are treating actual signed numbers, disregard the advice and cast directly from int8_t to int32_t.

Potatoswatter
  • 126,977
  • 21
  • 238
  • 404
  • 1
    Also, you don't even need the cast to make such an assignment: `int32_t b_32 = b;` this is also fine. – Marco Bonelli Mar 03 '21 at 13:09
  • 2
    “Text characters” can be negative; the C standard requires certain characters to be positive but allows negative characters otherwise (although it calls for `unsigned char` values for certain functions, such as those in ``). The issue here is the software OP is working with wants only non-negative values. It is specific to their situation, not a general rule. – Eric Postpischil Mar 03 '21 at 13:39
  • @EricPostpischil In ISO 8859, the authoritative standard, code points are positive values. C allows implementations to make `char` signed, but that does not change the choice of bindings from numbers to visual representations. The critical distinction is between `char` (unambiguously the name of an under-specified abstract data type) and "text characters" (unambiguously enough for this purpose, the name of the symbols that humans can read). – Potatoswatter Mar 03 '21 at 14:04
  • @Potatoswatter: C does not require ISO 8859. Printable characters resulting in symbols humans can read may have encodings in C that are negative values. – Eric Postpischil Mar 03 '21 at 14:05
  • @EricPostpischil The point is that this is not a pure language question. It is a question of applying the language to text processing vs. application to math processing. – Potatoswatter Mar 03 '21 at 14:06
  • @EricPostpischil Printable characters can have encodings which evaluate as negative when stored in `char`, but that does not imply that they properly have negative encodings. Encodings are solely defined by a standard such as ISO 8859. Negative codepoints would be tortuous to implementers, although it is within the realm of possibility. – Potatoswatter Mar 03 '21 at 14:09
  • @Potatoswatter: A problem I am trying to avoid is you teaching students that characters are positive, and they write code assuming that, and someday it fails. As I wrote, C does not have to use ISO 8859 or “codepoints.” There are C implementations that use negative values for characters in the `char` type, and students need to know to allow for that. Do not tell them text characters cannot be negative. Making some rationalizing that it is okay to say “text characters” are only positive is not going to prevent bugs by students who do not learn about negative characters. – Eric Postpischil Mar 03 '21 at 18:51
0

If you read the referred CERT-C rule you link to, the actual concern is to use char type in arithmetic or when storing raw values. They are also concerned about implicit type promotion. See these posts for more info about these issues:

Is char signed or unsigned by default?
Implicit type promotion rules

None of the concerns related to signedness of char or implicit integer promotion are present in your expression int32_t b_32 = (int32_t) b;. Notably, b is not of type char. No conversion to unsigned is necessary - the code is fine. The cast isn't needed either. Your tool is giving a false positive.

Lundin
  • 155,020
  • 33
  • 213
  • 341