Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't some languages allow declaration of pointers?

Tags:

c++

pointers

I'm programming in C++ right now, and I love using pointers. But it seems that other, newer languages like Java, C#, and Python don't allow you to explicitly declare pointers. In other words, you can't write both int x and int * y, and have x be a value while y is a pointer, in any of those languages. What is the reasoning behind this?

like image 497
wrongusername Avatar asked Nov 02 '10 04:11

wrongusername


4 Answers

Pointers aren't bad, they are just easy to get wrong. In newer languages they have found ways of doing the same things, but with less risk of shooting yourself in the foot.

There is nothing wrong with pointers though. Go ahead and love them.

Toward your example, why would you want both x and y pointing to the same memory? Why not just always call it x?

One more point, pointers mean that you have to manage the memory lifetime yourself. Newer languages prefer to use garbage collection to manage the memory and allowing for pointers would make that task quite difficult.

like image 151
Steve Rowe Avatar answered Nov 15 '22 20:11

Steve Rowe


I'll start with one of my favorite Scott Meyers quotes:

When I give talks on exception handling, I teach people two things:

  • POINTERS ARE YOUR ENEMIES, because they lead to the kinds of problems that auto_ptr is designed to eliminate.

  • POINTERS ARE YOUR FRIENDS, because operations on pointers can't throw.

Then I tell them to have a nice day :-)


The point is that pointers are extremely useful and it's certainly necessary to understand them when programming in C++. You can't understand the C++ memory model without understanding pointers. When you are implementing a resource-owning class (like a smart pointer, for example), you need to use pointers, and you can take advantage of their no-throw guarantee to write exception-safe resource owning classes.

However, in well-written C++ application code, you should never have to work with raw pointers. Never. You should always use some layer of abstraction instead of working directly with pointers:

  • Use references instead of pointers wherever possible. References cannot be null and they make code easier to understand, easier to write, and easier to code review.

  • Use smart pointers to manage any pointers that you do use. Smart pointers like shared_ptr, auto_ptr, and unique_ptr help to ensure that you don't leak resources or free resources prematurely.

  • Use containers like those found in the standard library for storing collections of objects instead of allocating arrays yourself. By using containers like vector and map, you can ensure that your code is exception safe (meaning that even when an exception is thrown, you won't leak resources).

  • Use iterators when working with containers. It's far easier to use iterators correctly than it is to use pointers correctly, and many library implementations provide debug support for helping you to find where you are using them incorrectly.

  • When you are working with legacy or third-party APIs and you absolutely must use raw pointers, write a class to encapsulate usage of that API.

C++ has automatic resource management in the form of Scope-Bound Resource Management (SBRM, also called Resource Acquisition is Initialization, or RAII). Use it. If you aren't using it, you're doing it wrong.

like image 44
James McNellis Avatar answered Nov 15 '22 20:11

James McNellis


Pointers can be abused, and managed languages prefer to protect you from potential pitfalls. However, pointers are certainly not bad - they're an integral feature of the C and C++ languages, and writing C/C++ code without them is both tricky and cumbersome.

like image 30
EboMike Avatar answered Nov 15 '22 20:11

EboMike


A true "pointer" has two characteristics.

  • It holds the address of another object (or primitive)
    • and exposes the numeric nature of that address so you can do arithmetic.

Typically the arithmetic operations defined for pointers are:

  1. Adding an integer to a pointer into an array, which returns the address of another element.
  2. Subtracting two pointers into the same array, which returns the number of elements in-between (inclusive of one end).
  3. Comparing two pointers into the same array, which indicates which element is closer to the head of the array.

Managed languages generally lead you down the road of "references" instead of pointers. A reference also holds the address of another object (or primitive), but arithmetic is disallowed.

Among other things, this means you can't use pointer arithmetic to walk off the end of an array and treat some other data using the wrong type. The other way of forming an invalid pointer is taken care of in such environments by using garbage collection.

Together this ensures type-safety, but at a terrible loss of generality.

like image 23
Ben Voigt Avatar answered Nov 15 '22 21:11

Ben Voigt