6

Looking at this answer and knowing that 0 is an octal constant:

For hexadecimal [constants [and octal according to the comments]], it is the first type the value can fit in: int, unsigned int, long, unsigned long, long long, unsigned long long

Therefore, I deduce this does not need a cast:

size_t foo = 0;

However, due to a strict MISRA-C lint tool, I get back a message about an illegal implicit type conversion - MISRA-C:2004 Rule 10.1.

Is my understanding wrong, or is the tool in error?

(NB: I've changed to size_t foo = 0U; as that is a lot simpler than arguing with QA, but I'd like to satisfy my own curiosity.)

Community
  • 1
  • 1
Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
  • How do you define to "need a cast"? There's an implicit conversion, and MISRA tells you about it. – juanchopanza Aug 06 '15 at 05:46
  • 1
    Also, since you tagged the question C, and not C++, here's [a question about `0` being octal in C](http://stackoverflow.com/questions/26625311/is-0-an-octal-or-a-decimal-in-c/). – juanchopanza Aug 06 '15 at 05:48
  • 7
    A decimal constant wouldn't need a cast either; any arithmetic type may be implicitly converted to any other arithmetic type. But `size_t foo = 0U;` may also involve an implicit conversion; `0U` is of type `unsigned int`, which may or may not be the same type as `size_t`. (And if MISRA requires a cast, MISRA is being silly.) – Keith Thompson Aug 06 '15 at 06:06
  • In this particular case there is no meaningful reason to sacrifice the type-independence of `0` initializer and replace it with a completely unnecessarily type-restricted `0U`. If MISRA requires it, it is back to the drawing board for MISRA. – AnT stands with Russia Aug 06 '15 at 06:25
  • 3
    @AnT - MISRA C:2012 Rule 10.3 explicity allows *a non-negitive interger constant expression of essentially signed type may be assigned to an object of essentially unsigned type if its value can be represented by that type* which is a standard-ese way of saying you don't need the U :-) – Andrew Aug 06 '15 at 07:40
  • MISRA-C:2004 does require the U but that has been superseded... and even for 2004 was widely (and reasonably IMHO) deviated! – Andrew Aug 06 '15 at 07:42
  • 1
    IINM it's not even possible to portably write out a `size_t` literal, since the whole point of `size_t` is to alias a type of unknown width... – Quentin Aug 06 '15 at 07:47
  • @Quentin huh? What is a type of unknown width? – M.M Aug 06 '15 at 08:58
  • [`typedef /*implementation-defined*/ size_t;`](http://en.cppreference.com/w/c/types/size_t) -- There's no way to know whether to initialize it with `0u`, `0ul` or `0ull`. – Quentin Aug 06 '15 at 09:06
  • but 0u will always work? Not sure what your point is. A size_t would have to be assigned (and cast) to a standard size (short, long, long long) before serialized for cross platform use. (not to int, because int size is platform dependent) – Michael Mar 14 '16 at 15:19

1 Answers1

3

I'm not sure what you are trying to achieve, but...

  • 0 is of type signed int
  • 0U is of type unsigned int

size_t requires type size_t - and sizes are (usually) unsigned

So for strict compliance size_t foo = 0U; although it might be more correct to use size_t foo = (size_t)0;

As an aside, discussion as to whether 0 is decimal, octal or anything else is irrelevant... it is still zero.

--

Edit to add:

Although explicit conversion between signed and unsigned was deprecated in MISRA C:2004 (although this was widely deviated), for MISRA C:2012 Rule 10.3 explicitly allows a non-negative integer constant expression of essentially signed type may be assigned to an object of essentially unsigned type if its value can be represented by that type

This is a standard-ese way of saying you don't need the U

Andrew
  • 2,046
  • 1
  • 24
  • 37