Both C# (unsafe) pointers and C++ (raw) pointers have the following characteristics:
- They allow you to reference an address in a given address space.
- They allow you to perform simple arithmetic operations (addition and subtraction) on them, involving integers as offsets.
- They allow you to dereference whatever they point to as data of a particular type.
- Wrong usage of them can invoke undefined behavior, making it exclusively your responsibility to ensure that you're using them correctly.
In that sense, and regardless of any minor differences (like syntax, pinning, etc), C# pointers and C++ pointers are pretty much the same programming concept. Therefore, they lend themselves to static analysis pretty much equally and thus they are equally safe or unsafe. So the fact that C# explicitly calls this construct out as unsafe
doesn't make the equivalent C++ construct "safe". Rather, the ability to use "unsafe" code is "always on" in C++.
As an example, consider the case where you attempt to access an array using an index that's out of bounds:
- With a C# array you will get an exception when using the indexer syntax and you will invoke undefined behavior when using a pointer and an offset.
- With a C-style array in C++ you will invoke undefined behavior when using either the indexer syntax or a pointer and an offset (because those two syntaxes are equivalent for C-style arrays).
- With a C++11
std::array
you will get an exception when using array::at
and you will invoke undefined behavior when using the indexer syntax.
unsafe
is a keyword in the C# language. – Allay