HN user

xcgvgh

1 karma
Posts2
Comments14
View on HN

There is no reinventing going on here. In C you have to write relatively low level code. This includes manually calling allocs for objects, which includes the code for checking your arithmetic. At some point you will have to write that code. If you are smart you will wrap it into a function.

Using calloc instead of malloc, just for checking arithmetic overflow, is superfluous. You can always write a check or a wrapper for malloc that does that automatically. It is so easy I can write it here:

  _Bool Check( const size_t a , const size_t b )
  {
    if( a > SIZE_MAX / b )
    {
       return false;
    }
    return true;  
  }
(If proper warnings are enabled, it also provides extra integer type checking.)

The assignment is a conversion from unsigned to signed, if the value cannot be represented by the signed type, the result is implementation defined or an implementation defined signal is triggered.

I understand.

If I change the argument to: size_t is capable of holding the largest array index", then this must be correct, or is there still something I missed?

size_t is defined as "an integer capable of holding the >largest array index"

>No, it isn't.

Could anyone elaborate?

I don't see how could someone allocate more than SIZE_MAX bytes with (m/c/re)alloc since they all take size_t as an argument, and size_t is the type used for defining array sizes. Thus size_t can hold the largest array index (in fact it can hold the largest_index+1 since arrays are zero based). Any counterarguments?

How to C in 2016 11 years ago

Typedef doesn't create a new type, it merely creates a new name for a type. I don't know what you mean by implementation defined integer type. If the implementation is conforming, then any integer type that isn't a basic C integer type, is really just a typedef for one of the basic C integer types ( char, short int, int, long, ... ).

In C, with CHAR_BIT defined as 8, unsigned char is the only type that satisfies the requirements of uint8_t.

( It is also possible that it is defined as char, if implementation defines char to have the same range, representation, and behavior as unsigned char. In this case, char effectively becomes unsigned char, but is still a distinct type. The types are compatible (can alias).)

Now why is unsigned char the only possibility. Type uint8_t is defined to have two'2 complement, have exactly 8 bits, no padding, and be unsigned. So we need an unsigned integer type. The unsigned type that follows unsigned char in rank is unsigned short char. But this type is defined to have ranges at least from 0 to 65535. Since CHAR_BIT is 8, unsigned short int cannot be used, because it has to have more than 8 bits. As there is no type in rank before unsigned char, it remains the only possibility.

How to C in 2016 11 years ago

In the second to last paragraph; did you hint that wrapping a char*, used as a string, into a struct, to get type safety?

How to C in 2016 11 years ago

I use long when I need an int that can always represent ranges in -2^31-1 to 2^31-1, no assumptions necessary.

Same goes for unsigned versions and long long.