2

If I set a size_t variable to -1, like in:

size_t s = -1;

Is it guaranteed it will contain the maximal value that can be hold by s?

For example, if sizeof(size_t) is 4 bytes, can I assume that s would be 0xFFFFFFFF?

As a complementary info: I need this for implementing a set, in which I intend to use -1 as 'item doesn't exist'. And at the same time I don't want to sacrifice the 0, nor using an int.

Bite Bytes
  • 1,455
  • 8
  • 24
  • No warning from `gcc -Wall -Wextra`. – Antti Haapala -- Слава Україні Jul 28 '17 at 17:36
  • @MikeMB I think `~0` is not guaranteed (well, at least not explicitly) to give the maximal value by the standard, while `-1` is. – Eugene Sh. Jul 28 '17 at 17:45
  • @MikeMB I was thinking about padding bits. But apparently [this](https://stackoverflow.com/questions/4475540/c-question-padding-bits-in-unsigned-integers-and-bitwise-operations-c89) is telling that the bitwise operations should not affect these. So yeah, as I said it is probably correct but not as obvious from the standard. – Eugene Sh. Jul 28 '17 at 18:17
  • @MikeMB `~0` will not work on rare non-2's complement platforms to give maximum `size_t`. `~0u` will fail when `SIZE_MAX > UINT_MAX`. Hard to beat `size_t s = SIZE_MAX;` – chux - Reinstate Monica Jul 28 '17 at 19:24
  • ["unsigned integers are guaranteed to be represent as two's complement."](https://stackoverflow.com/questions/45379143/setting-a-size-t-variable-to-1/45381164#comment77721269_45379143) --> two's complement is for signed integers. Unsigned integers do not use two's complement. – chux - Reinstate Monica Jul 28 '17 at 19:40
  • @WeatherVane: It did for me with VS2017. Which version are you using? And what warning level? – MikeMB Jul 28 '17 at 19:51
  • @chux: You are right, that doesn't make sense. I have to check back what I did exactly. I removed the comments. – MikeMB Jul 28 '17 at 19:52
  • @MikeMB MSVC 2015 with default warning level from console not IDE. If yours did give you a warning, you must be right, but it read like you were guessing, or read it on the internet ;) – Weather Vane Jul 28 '17 at 20:02
  • @WeatherVane: I did check here: https://godbolt.org/g/nFH3iw (I'm always compiling with /W4 on MSVC). What I did guess (poorly) was the syntax of my solution. As was written by chux and in the answers: The sane thing to do is using `SIZE_MAX`. – MikeMB Jul 28 '17 at 21:18
  • @MikeMB I wonder if there is a difference here between my C and your C++. – Weather Vane Jul 28 '17 at 21:23
  • Can you not pass in the value to be modified as a reference or pointer, and have the function just return an error code? Example: `int some_function(size_t* val) { *val = 42; return -1; }` ..? – txtechhelp Jul 29 '17 at 01:49
  • @txtechhelp I don't want to modify them, just storing them, and retrieve them later. – Bite Bytes Jul 29 '17 at 11:57

2 Answers2

5

Yes, it is guaranteed to become the maximum, since size_t is always an unsigned integer type, and unsigned integer types are guaranteed to wrap / use modulo arithmetic. As C11 6.3.1.3p2 says of converting integers (-1 is a constant of type int) to unsigned integer types.

[...] if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.


However, sizeof(size_t) == 4 doesn't mean that it has 32 bits, because sizeof tells the size in bytes - i.e. chars - and a char has CHAR_BIT bits. And even if sizeof(size_t) * CHAR_BIT == 32, size_t can still have less than 32 value bits (the rest will be padding bits).


P.S. I'd recommend that you use SIZE_MAX from <stdint.h> instead.

1

To @Antti Haapala fine answer, I added this to address OP's higher goal.

As a complementary info: I need this for implementing a set, in which I intend to use -1 as 'item doesn't exist'. And at the same time I don't want to sacrifice the 0, nor using an int.

Instead of a naked magic number like -1, define a value. Rather than -1, use SIZE_MAX. It is the right value and the matching promoted type.

#include <stdint.h>
#define ITEM_NO_EXIST (SIZE_MAX)

...
// size_t s = -1;
size_t s = ITEM_NO_EXIST;
...
if (s == ITEM_NO_EXIST) puts("Item does not exist");
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256