If C# pointers are considered "unsafe," does that mean C++ pointers are "unsafe" too?
Asked Answered
D

4

6

I am doing a project in C#, which could benefit from a linear algebra package. I've looked at the ones out there, but I don't really want to pay, or I found them not very good. So I decided to write my own.

I read that C++ arrays are much faster than C# arrays, but that it was possible to get similar performance using pointer arrays in C#, although they are considered "unsafe." I'm curious to know how C++ pointers differ, and if the "unsafe-ness" applies to C++ as well, or if they are two fundamentally different things.

Dandle answered 15/5, 2016 at 16:16 Comment(7)
What does "safe" mean?Hoffer
Whatever your definition of "unsafe" happens to be, if it applies to C# pointers, then I'm sure it also applies to C++ pointers. However, C++ does not have a well-defined concept of "unsafe" the way C# does.Teaspoon
@BenjaminLindley: unsafe is a keyword in the C# language.Allay
@MartinBonner: Yes, I understand that. It's also a word in the English language, and it is not entirely clear in what manner the OP is using it.Teaspoon
@MartinBonner: Just realized that may have sounded snarky (the "It's also a word in the English language" part), and didn't intend it to.Teaspoon
Do you remember where did you read about the mentioned C# vs C++ array performance comparison? Could you share your resources with us?Matchlock
Was looking at this, and some other stuff: codeproject.com/Articles/212856/…Dandle
M
9

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.
Musicale answered 15/5, 2016 at 16:36 Comment(1)
Your first bullet needs a tweak, code that uses the dynamic keyword or Reflection cannot be verified statically by the C# compiler either. It is the verifier built into the CLR that can't do its job.Waxbill
A
2

Roughly speaking (and it is a very crude approximation), a C# unsafe pointer is the same sort of thing as a C++ pointer.

With both, there is a lot more responsibility on the programmer to get it right whereas with normal C# if you get things wrong, the worst that will happen is that an exception will be thrown. The run-time checks that give those guarantees cost performance, but if you switch them off - you are on your own.

Allay answered 15/5, 2016 at 16:23 Comment(0)
F
2

unsafe means that .Net grants you access to memory that you did not necessarily allocate. The bound checking is turned off which allows some optimizations in the JIT compiler.

In general, pointers are the same in C++, that is they grant you access to any region of memory. You can implement bound-checking with operator overloading, but it isn't the default for pointers.

Farron answered 15/5, 2016 at 16:26 Comment(0)
G
2

In particular, unsafe in C# means can break out of the managed sandbox and execute native code. This then means your managed code can generate unmanaged crashes. This is also why unsafe code is not allowed without full trust (but you probably don't have to deal with partial trust code anymore).

You're probably thinking how can I run unmanaged code with an int * in C#. Easy: deliberate stack smashing. Assign it to the address of an integer on the stack and write to the next few integers the address of a byte array containing native code.

Groundhog answered 15/5, 2016 at 16:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.