views:

295

answers:

5

According to Wikipedia:

An object is first-class when it:

  • can be stored in variables and data structures
  • can be passed as a parameter to a subroutine
  • can be returned as the result of a subroutine
  • can be constructed at runtime
  • has intrinsic identity (independent of any given name)

Somebody had once told me that raw pointers are not first class objects while smart pointers like std::auto_ptr are. But to me, a raw pointer (to an object or to a function) in C++ does seem to me to satisfy the conditions stated above to qualify as a first class object. Am I missing something?

+1  A: 

From wiki:

In computing, a first-class object (also value, entity, and citizen), in the context of a particular programming language, is an entity which can be passed as a parameter, returned from a subroutine, or assigned into a variable.1 In computer science the term reification is used when referring to the process (technique, mechanism) of making something a first-class object.[citation needed]

I included the entire entry in wiki-pedia for context. According to this definition - an entity which can be passed as a parameter - the C++ pointer would be a first class object.

Additional links supporting the argument: catalysoft wapedia

reification: referring to the process (technique, mechanism) of making something a first-class object

dboarman
Reification: King me!
quixoto
A: 

As Mike commented there seems to be a bit of confusion with the word Object here. Your friend seems to be confusing between objects as in "first class objects" and Objects as "instances of C++ classes", two very different things where the word object is used for two things completely different.

In Object Oriented programming, the word Object is used to speak of some data structure gathering datafields and methods to manipulate them. With C++ you define them in classes, get inheritance, etc.

On the other hand in the expression "first class object" the word object has a much broader meaning, not limited to Objects of object oriented languages. An integer qualify as a first class object, a pointer also do. I believe "Objects" with the other meaning does not really qualify as first class object in C++ (they do in other OO programming languages) because of restrictions on them on parameter passing (but you can pass around pointers or references to them, the difference is not so big).

Then the things are really the opposite of what you friend said: pointers are first class objects but are not instances of C++ classes, smart pointers are instances of C++ classes but are not first class objects.

kriss
+3  A: 

The definition in Wikipedia of "first-class" is incorrect. In a programming language, an entity is considered to be "first-class" if it does not require any special treatment by the compiler and can be interpreted, understood, used, etc. just like any other object in the language. The reason pointers in C++ are not first class objects is that *p for a pointer p is not interpreted as simply invoking an overloaded operator* like it would be for any other object; instead, the compiler has to treat p specially based on the fact that it is a pointer type. When passing a pointer or a reference you cannot simply pass any value object (and some of those value objects happen to be pointers), but you are actually saying that it is a different type (a pointer type or a reference type, in place of a value type), and its interpretation / usage is subject to its type.

A good example of a language where all objects are first-class is Python. In Python, everything has some sort of type associated with it, it can be treated as an object, it can have members, functions, etc. As an extreme example, even functions in Python are objects that simply contain code and happen to be callable; in fact, if you try to call the function using the __call__ member function (which is akin to overloading operator() in C++, and which other non-function objects can provide), an ordinary function will return a function wrapper as a result (so that you don't have to treat functions as a special case). You can even add members to functions like you would to other objects. Here is an example of such a thing:

>>> def f(x):
...     return x;
... 
>>> func = f;
>>> print f.__class__

>>> print f(5)
5
>>> print f.__call__(5)
5
>>> f.myOwnMember = "Hello world!"
>>> print f.myOwnMember
Hello world!

I apologize for the Python in a C++ post, but it is hard to explain the concept without the contrast.

Michael Aaron Safyan
@Aaron: I believe the expression "first class object" came before OOP. Python objects are indeed "first class objects", but object here is not the same word as in Object Oriented.
kriss
@Arron; and about wikipedia article on the subject, you should read given examples to get the context of use of the word "object".
kriss
@Aaron: I know Python, so its fine to see Python code :). Does the Wikipedia page need a revamp in this case? I wish some more ppl can confirm your explanation.
Shailesh Kumar
@kriss, @Shailesh, BTW, my name is Michael. Aaron is my middle name (and I only use it online because there is a different Michael Safyan on the web). I would prefer it if you would call me Michael or Mike.
Michael Aaron Safyan
@Shailesh, that is the definition of "first class" that I learned in "CSE 425: Programming Languages and Systems" at WashU and alsoo in "CSE 431: Translation of Programming Languages" (a.k.a. "Compilers"). I do not have any online sources to give you, though.
Michael Aaron Safyan
@Shailesh, if you can find sufficient sources, then go for it. Wikipedia, unfortunately, requires things to be sourced (even if there are a plethora of incorrect sources that circularly cite each other but only one source that correctly refutes them), although it looks like the article in question is currently poorly sourced, anyway.
Michael Aaron Safyan
@kriss, I agree, it does not necessarily need to be an object. But all the properties of the typical datatype (whether that is an object or a builtin primitive type) need to be present/used rather than special-cased for it to be considered a "first class" citizen of the type world.
Michael Aaron Safyan
Take a good hard look at section 13.6 of the standard, "built-in operators." It explains how operators for every native type fit into the overloading scheme, whether or not they are actually overloadable. So although the *user* cannot overload `operator*(int*)`, the compiler is required to act as if overload resolution occurs.
Potatoswatter
Sorry, but that's BS. By that definition, in every language which has stock non-overloadable arithmetic operators for, say, integers, integers aren't first-class. It also sounds like your definition uses the word "object" in OO sense, which is definitely very wrong (the concept was in use long before the earliest OO experiments).
Pavel Minaev
Michael Aaron Safyan
@Pavel, you are misinterpreting my explanation. You can have non-overloadable arithmetic operators, but non-builtins and builtins would have to be treated similarly for them to be first class.
Michael Aaron Safyan
+2  A: 
Norman Ramsey
+1  A: 

Actually both - "Pointers are FCO" and "Pointers are not FCO" - are correct. We need to take the statements in the respective context. (FCO - First Class Object)

When we talk of a 'pointer' in C++, we are talking of a data type that stores the address of some other data. Now whether this is FCO or not, depends really on how we envisage to use it. Unfortunately, this use semantics is not built-in for Pointers in C++.

If we are using pointers merely to 'point' to data, it will satisfy the requirements of being an FCO. However, if we use a pointer to 'hold' a data, then it can no longer be considered an FCO as its copy and assignment semantics do not work. Such 'resource handling' pointers (or more directly referred as 'raw pointers') are our interest in the context of Smart Pointer study. These are not FCO while the corresponding Smart Pointers are. In contrast, mere tracking pointers would continue to meet the requirements for an FCO.

The following paragraph from "Modern C++ Design" book nicely elucidates the point.

I quote from the Chapter on Smart Pointers:

An object with value semantics is an object that you can copy and assign to. Type int is the perfect example of a first-class object. You can create, copy, and change integer values freely. A pointer that you use to iterate in a buffer also has value semantics—you initialize it to point to the beginning of the buffer, and you bump it until you reach the end. Along the way, you can copy its value to other variables to hold temporary results.

With pointers that hold values allocated with new, however, the story is very different. Once you have written

Widget* p = new Widget; the variable p not only points to, but also owns, the memory allocated for the Widget object. This is because later you must issue delete p to ensure that the Widget object is destroyed and its memory is released. If in the line after the line just shown you write

p = 0; // assign something else to p you lose ownership of the object previously pointed to by p, and you have no chance at all to get a grip on it again. You have a resource leak, and resource leaks never help.

I hope this clarifies.

Partha Pratim Das