Question: I have the below simple program:

```
#include <iostream>
#include <stdio.h>

void SomeFunction(int a)
{
  std::cout<<"Value in function: a = "<<a<<std::endl;
}

int main(){

  size_t a(0);

  std::cout<<"Value in main: "<<a-1<<std::endl;
  SomeFunction(a-1);

  return 0;

}

```

Upon executing this I get:

> 
> Value in main: 18446744073709551615
> 
> 
> Value in function: a = -1
> 
> 
> 

I think I roughly understand why the function gets the 'correct' value of -1: there is an implicit conversion from the unsigned type to the signed one i.e. 18446744073709551615(unsigned) = -1(signed).

Is there any situation where the function will not get the 'correct' value?

Answer: 
Since `size_t` type is unsigned, subtracting `1` is well defined:

> 
> A computation involving `unsigned` operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.
> 
> 
> 

However, the resultant value of 264-1 is out of `int`s range, so you get implementation-defined behavior:

> 
> [when] the new type is signed and the value cannot be represented in it, either the result is implementation-defined or an implementation-defined signal is raised.
> 
> 
> 

Therefore, the answer to your question is "yes": there are platforms where the value of `a` would be different; there are also platforms where instead of calling `SomeFunction` the program will raise a signal.
Not on your computer... but technically yes, there is a situation where things can go wrong.

All modern PCs use the "two's complement" system for signed integer arithmetic (read Wikipedia for details). Two's complement has many advantages, but one of the biggest is this: *unsaturated addition and subtraction of signed integers is identical to that of unsigned integers*. As long as overflow/underflow causes the result to "wrap around" (i.e., 0-1 = UINT\_MAX), the computer can add and subtract without even knowing whether you're interpreting the numbers as signed or unsigned.

BUT! C/C++ do not technically *require* two's complement for signed integers. There are two other permissible systems, known as "sign-magnitude" and "one's complement". These are unusual systems, never found outside antique architectures and embedded processors (and rarely even there). But in those systems, signed and unsigned arithmetic do not match up, and `(signed)(a+b)` will not necessarily equal `(signed)a + (signed) b`.

There's another, more mundane caveat when you're also narrowing types, as is the case between `size_t` and `int` on x64, because C/C++ don't require compilers to follow a particular rule when narrowing out-of-range values to signed types. This is likewise more a matter of language lawyering than actual unsafeness, though: VC++, GCC, Clang, and all other compilers I'm aware of narrow through truncation, leading to the expected behavior.