8

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?

alex
  • 479,566
  • 201
  • 878
  • 984
Shailesh Kumar
  • 6,457
  • 8
  • 35
  • 60
  • 8
    Pointers are definitely first-class objects in both C and C++. You might want to ask this person where he got his definition from, because it's clearly non-mainstream. Or maybe he confused pointers with C++ references (&), which aren't first-class? – Pavel Minaev Apr 22 '10 at 23:16
  • 9
    He might also have been confusing the word "object" in "first class object" for the object-oriented concept of an "object", which pointers aren't. – Mike Daniels Apr 22 '10 at 23:21
  • 2
    Although the type traits template pattern allows us to imbue random objects with random new methods, regaining whatever was lost by omitting a master `Object` class… – Potatoswatter Apr 22 '10 at 23:29
  • 1
    That Wikipedia article is terrible. Maybe after graduation I can fix it. – Norman Ramsey Apr 23 '10 at 05:33
  • 1
    To make matters even more confusing, C++ has its own definition of "object" (given in ISO C++ standard), inherited from C, and distinct from OOP objects. By that C++ definition, a pointer is an object, and so is an int, for example - but a reference (T&) is not. – Pavel Minaev Apr 23 '10 at 06:19
  • @MikeDaniels: wasn't it convenient to classify fundamental types as objects as well ? Notably so that you can program generically when using typename T in template. You should be able to say "T is an object", and not forced to say "T is an object or a fundamental", no ? – v.oddou Dec 13 '13 at 05:29

5 Answers5

3

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
  • 93,612
  • 16
  • 138
  • 200
  • 1
    @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 Apr 23 '10 at 00:02
  • @Arron; and about wikipedia article on the subject, you should read given examples to get the context of use of the word "object". – kriss Apr 23 '10 at 00:05
  • @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 Apr 23 '10 at 00:13
  • @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 Apr 23 '10 at 01:22
  • @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 Apr 23 '10 at 01:24
  • @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 Apr 23 '10 at 01:26
  • @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 Apr 23 '10 at 01:29
  • 2
    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 Apr 23 '10 at 05:59
  • 3
    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 Apr 23 '10 at 06:17
  • @Potatoswatter, I fail to see how that is relevant. The fact of the matter is you cannot, for example, take the address of "int& int*::operator*()const" or of "int* int*::operator->()const". – Michael Aaron Safyan Apr 23 '10 at 12:57
  • @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 Apr 23 '10 at 12:59
2

The Wikipedia article is shit (for once I agree with "citation needed"), but you are not missing anything: according to the Wikipedia definition, and also according to any sane definition, raw C++ pointers are first-class objects.

If anyone would like to volunteer to help me with some searches through Google Scholar, I would really like to see that Wikipedia article fixed. I am a subject-matter expert, but I am also extremely busy—I would love to have a partner to work on this with.

Norman Ramsey
  • 198,648
  • 61
  • 360
  • 533
1

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

IAbstract
  • 19,551
  • 15
  • 98
  • 146
1

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
  • 23,497
  • 17
  • 97
  • 116
1

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.

  • 1
    My god no, this is a confusion. I disagree with Alexandrescu on this one. There is no such thing as "resource owner raw pointer", a raw pointer is a first class citizen, end of line. Yes a `unique_ptr` is resource owning, but you can not ask a raw pointer to be smart, it is what it is, and can be copied and then what, 2 pointers are resource owners ? This "vue de l'esprit" is wrong, the owner is not the pointer, it is the manager (object that holds the pointer) that is the owner. A smart pointer is small manager with a raw pointer inside. – v.oddou Dec 13 '13 at 05:40