tags:

views:

429

answers:

7

Does the FILE type used through standard C functions fopen, etc. have an object-oriented interface?

I'm looking for opinions with reasoning rather than an absolute answer, as definitions of OO vary by who you ask. What are the important OO concepts it meets or doesn't meet?

In response to JustJeff's comment below, I am not asking whether C is an OO language, nor whether C (easily or not) allows OO programming. (Isn't that a separate issue?)

+1  A: 

No. C is not an object-oriented language.

I know that's an "absolute answer," which you didn't want, but I'm afraid it's the only answer. The reasoning is that C is not object-oriented, so no part of it can have an "object-oriented interface".

Clarification:

In my opinion, true object-orientation involves method dispatch through subtype polymorphism. If a language lacks this, it is not object-oriented.

Object-orientation is not a "technique" like GTK. It is a language feature. If the language lacks the feature, it is not object-oriented.

If object-orientation were merely a technique, then nearly every language could be called object-oriented, and the term would cease to have any real meaning.

Gregory Higley
Thats really odd logic - "A house is not white, so no part of it can be white.".
Justicle
If C lacks the machinery of object-orientation, how can any part of it be object-oriented?
Gregory Higley
By writing the machinery yourself in C. By playing games with casting to void and building your own vtables you can support inheritance, polymorphism, and encapsulation in C, it's just a pain in the ass to do it. The original C++ implementations generated C source which was then compiled.
Charles E. Grant
I'm not trying to get at the roots of C, but the roots of polymorphism. I specifically asked about a concrete example, which is (IMHO) borderline, in order to avoid pure theory. Polymorphism seems to be a key requirement to you, perhaps the most important? Are there other requirements?
Roger Pate
On a separate but related note, if FILE does not have a polymorphic interface, do file descriptors meet that requirement? If so, are they object orientated or in which ways are they still lacking?
Roger Pate
There is no ANSI standard for what constitutes 'object oriented', just commonly held opinions. Some folks will passionately argue that C++ doesn't "really" support object oriented programming. The definitions I've run into most frequently say that object orientation requires support for encapsulation, inheritance, and polymorphism, but that is just a useful rule of thumb not a mathematical truth. With some pain you can provide those features in C, but they were not provided for the FILE structure or file descriptors or sockets.
Charles E. Grant
Well, this is why I said (and emphasized) "in my opinion". "By playing games with casting to void and building your own vtables" and so on. Yep, you can create something that looks like object-orientation in almost any language. But if this makes the language object-oriented, doesn't it make "object-oriented" a useless distinction?
Gregory Higley
The distinction should lie in the software design, not in the language it is implemented in.
dreamlax
File descriptors and sockets are just integers that are indexes into some table in the operating system memory. There are some operations that look polymorphic, say the read function. But there are other operations that done respect polymorphism. If you pass a file descriptor instead of a socket to listen(), listen will fail and register an error.
Charles E. Grant
@Gregory, I think that actually exactly why the distinction is useful. I can write a purely procedural program in C++, and a program using encapsulation, polymorphism, and inheritance in C. If I just tell you the language, I still haven't told you how I actually organized the program.
Charles E. Grant
@Gregory: I think the initial negative reaction stems from your initial (unclarified) answer being absolute, without qualification. And I think you're very right, that claiming a language "is OO" is pretty useless. If you're still interested in this topic, what else besides polymorphism do you think is a requirement for object orientation, or OOP? (Asked before but didn't direct specifically at you.) And how might the FILE interface meet or fall short of these requirements?
Roger Pate
@Charles: isn't all OO essentially implemented as integers that are indexes to some table? This is how C++, Java, and Python handle it, from my understanding.
Roger Pate
@r-pate To call a language object-oriented, I think it has to have subtype polymorphism as a first-class language feature, which means that methods are dispatched based on the type of the hidden first parameter, depending upon its place in the inheritance hierarchy. (Hence, "subtype polymorphism".) Sure, you can simulate this in C and many other languages, but there it is not a first-class language feature. Again, my opinion.
Gregory Higley
@R. Pate, a fair point.
Charles E. Grant
@Gregory Higley, I would agree that is not useful to classify C as an OO language, but that's not the question R. Pate asked, and specifically eschewed. The original question was whether the FILE data structure had an OO interface. My only point is that an OO interface supporting inheritance and polymorphism could have been written in 'C', but was not (thank god), they settled for encapsulation.
Charles E. Grant
Though I was (apparently) originally not clear enough that I was asking about a specific interface, rather than C itself. (My apologies.)
Roger Pate
@r-pate No, you were perfectly clear, but because I do not believe that C is object-oriented in any form, it follows that FILE is not object-oriented in any form (as far as I'm concerned). Others think differently, but it boils down to semantics: "What's your definition of object-oriented?" I think one thing, others think differently, but as long as we're clear and define our terms, no harm no foul.
Gregory Higley
+4  A: 

Is C an object-oriented language?

Was OOP (object-oriented-programming) anything more than a laboratory concept when C and FILE were created?

Answering these questions will answer your question.

EDIT:

Further thoughts: Object Oriented specifically means several behaviors, including:

Inheritence: Can you derive new classes from FILE?

Polymorphism: Can you treat derived classes as FILEs?

Encapsulation: Can you put a FILE inside another object?

Methods & Properties: Does a FILE have methods and properties specific to it? (eg. myFile.Name, myFile.Size, myFile.Delete())

Although there are well known C "tricks" to accomplish something resembling each of these behaviors, this is not built in to FILE, and is not the original intent.

I conclude that FILE is not Object Oriented.

abelenky
Even though the language isn't specifically geared towards object-oriented development, that doesn't mean that you can't implement object-oriented interfaces manually (using structs and function pointers). Take GLib/GObject for example.
dreamlax
As to your edit, I was more-or-less targeting my argument at your first question; the answer to which is debatable and would not help in answering R. Pate's original question.
dreamlax
Are functions such as fopen, fclose, freopen not methods of FILE objects? Is the distinguishing feature of methods the mere language syntax that you call them through a.b syntax?
Roger Pate
I think there is more to OO than will be answered on SO as a result of this question.
John Saunders
Like R.Pate said, you seem to define OO-ness as a property of syntax. It is object-oriented if the method call includes a dot, is basically what it sounds like. fopen seems like a "method specific to a FILE" to me. Don't you agree?As for encapsulation, doesn't a FILE encapsulate all the internal details? Are you able to poke around inside a FILE accessing implementation details that you shouldn't concern yourself with? It seems pretty well encapsulated to me. Polymorphism? I can treat a socket, or stdin/stdout as files. Is that not polymorphic behavior?
jalf
@jalf: Still can't subclass it. Subclassing is generally viewed as an important part of OO, so without the ability to subclass FILE, it does not meet the definition on entirely functional terms, disregarding syntax.
Chuck
Subclassing is only viewed as important in object-oriented languages that use classes to implement objects.
dreamlax
@jalf: I don't think you can pass a socket to fread/fwrite. You have to call fdopen on it which first, which gives you a FILE which wraps the socket. No polymorphism going on there, just composition.
Charles E. Grant
Isn't stdout (which is a FILE*) a socket in traditional CGI implementations?
Roger Pate
@R.Pate: It can be, or it could be a fifo. This gets set up outside the process though, and is still just composition; the polymorphism is happening at the file descriptor level
bdonlan
No. The underlying FILE data structure may <i>contain</i> a socket (or a file descriptor, or a buffer), but it is not itself a socket. You can't pass a FILE * to a function that expects a socket (bind for example), and you can't pass a socket to a function that expects a FILE * (fclose for example). In the usual usage of the word polymorphism, you'd have to be able to pass a FILE anywhere you'd pass a socket or visa versa depending on which way you are claiming the inheritance runs.
Charles E. Grant
@bdonlan, Charles: Thanks for the clarifications. Perhaps the better question is "are file descriptors object orientated?" then?
Roger Pate
@Charles, i think this is nit-picking at this end. you may aswell argue that base-classes in C++ are aswell just "contained" as sub-objects within another complete object. "You can't pass a FILE * to a function that expects a socket" -> You may also not pass an animal to a function expecting a dog. "you can't pass a socket to a function that expects a FILE *" you can. fread could read from the socket, for example. and fclose could close the socket or could be just a no-op
Johannes Schaub - litb
No, composition is definitely a different technique then inheritance. In classic OO pedagogy, inheritance implements the "is a" predicate, while composition implements "has a". You can pass a socket or a file descriptor to read and close, but calls fread and fclose won't even compile if you pass them anything but a FILE *.
Charles E. Grant
@Charles: The "is a" vs "has a" distinction makes no sense in this case. A file descriptor (FILE*) defines one interface that has many different implementations. A file descriptor may be a file, or it may be a socket, or it may be almost anything else. That is the textbook definition of polymorphism. It "allows different data types to be handled using a uniform interface". Or "the ability of one type to appear and be used like another type". A FILE* certainly allows that. Composition does not give you that. Composition can never allow a socket to look like a file descriptor.
jalf
@jaff: "A file descriptor may be a file, or it may be a socket," That's most likely because, on the system it originated on (UNIX), *everything* is a file
R. Bemrose
+1  A: 

Academically speaking, certainly the actual files are objects. They have attributes and you can perform actions on them. Doesn't mean FILE is a class, just saying, there are degrees of OO-ness to think about.

The trouble with trying to say that the stdio FILE interface qualifies as OO, however, is that the stdio FILE interface doesn't represent the 'objectness' of the file very well. You could use FILEs under plain old C in an OO way, but of course you forfeit the syntactic clarity afforded by Java or C++.

It should probably further be added that while you can't generate 'inheritance' from FILE, this further disqualifies it as OO, but you could argue that's more a fault of its environment (plain C) than the abstract idea of the file-as-object itself.

In fact .. you could probably make a case for FILE being something like a java interface. In the linux world, you can operate almost any kind of I/O device through the open/close/read/write/ioctl calls; the FILE functions are just covers on top of those; therefore in FILE you have something like an abstract class that defines the basic operations (open/read/etc) on an 'abstact i/o device', leaving it up to the various sorts of derived types to flesh those out with type-specific behavior.

Granted, it's very hard to see the OO in a pile of C code, and very easy to break the abstractions, which is why the actual OO languages are so much more popular these days.

JustJeff
Is something not OOP just because it's not syntactically clear? Do you consider syntactic clarity a requirement for OOP?
Roger Pate
personally? no. i think that OO-ness ultimately resides in design. that fact that some languages have syntax that allows a mere implementation to express those aspects of the design is merely a nicety. And in contrast, there is PLENTY of classic procedural/structured programming done in Java and touted as "OO" merely b/c "the language is OO", as if somehow the OO-ness of the language imbues anything rendered in it as also inherently OO.
JustJeff
"as if somehow the OO-ness of the language imbues anything rendered in it as also inherently OO" -- seems very true to me. How about the inverse: If a language's OO support is minimal, or non-existant, does that make anything rendered in it inherently non-OO?
Roger Pate
what KINDS of things qualify as OO?can a design be OO? sure! can a language be OO? indeed! can an implementation of a system be OO? Yes, somewhat independently of whether the underlying language is. Can a PART of a language be OO? You as well might ask, can one blade of grass be a lawn?
JustJeff
+3  A: 

If the FILE type were "object oriented", presumably we could derive from it in some meaningful way. I've never seen a convincing instance of such a derivation.

Lets say I have new hardware abstraction, a bit like a socket, called a wormhole. Can I derive from FILE (or socket) to implement it. Not really - I've probably got to make some changes to tables in the OS kernel. This is not what I call object orientation

But this whole issue comes down to semantics in the end. Some people insist that anything that uses a jump-table is object oriented, and IBM have always claimed that their AS/400 boxes are object-oriented, through & through.

For those of you that want to dip into the pit of madness and stupidity that is the USENET comp.object newsgroup, this topic was discussed quite exhaustively there a few years ago, albeit by mad and stupid people. If you want to trawl those depths, the Google Groups interface is a good place to start.

anon
depends on how you define derivation. Sockets and many other things fit nicely into the FILE abstraction too. In posix, almost everything is a FILE. Are they all derivations of the same interface? (I didn't downvote you btw, just for the record.)
jalf
Or upvote, I notice!
anon
lol, just did. :p
jalf
Wow! Neil's rep went from 21.9K to 21.9K by your upvote! Have another, let's see it clock over to 22K.
dreamlax
A rep recalc must have happened. Unfortunately I'm over the cap so more gratuitous upvotes won't have any effect. Don't let that stop you all though!
anon
@Neil: does this mean all those classes (in other languages normally considered to be OO languages) that don't allow derivation ('final class', 'sealed', etc.) aren't OO to you?
Roger Pate
@R.Pate Those languages do allow derivation - they also allow its prevention. You seem to be setting up a false dichotomy. To be frank, I'm not all that interested in whether a language is OO - I'm more interested in whether it is useful.
anon
@Neil: Right, those languages allow derivation, but the specific classes obviously don't. Therefore would the classes be written in a non-OO style, if derivation is a requirement of OO-style? Is it a requirement of OOP?
Roger Pate
And finally we get to the interesting bit. Who cares if it is OO? Is it *useful*?
jalf
+2  A: 

It depends. How do you define an "object-oriented interface"? As the comments to abelenky's post shows, it is easy to construct an argument that FILE is object-oriented. It depends on what you mean by "object-oriented". It doesn't have any member methods. But it does have functions specific to it.

It can not be derived from in the "conventional" sense, but it does seem to be polymorphic. Behind a FILE pointer, the implementation can vary widely. It may be a file, it may be a buffer in memory, it may be a socket or the standard output.

Is it encapsulated? Well, it is essentially implemented as a pointer. There is no access to the implementation details of where the file is located, or even the name of the file, unless you call the proper API functions on it. That sounds encapsulated to me.

The answer is basically whatever you want it to be. If you don't want FILE to be object-oriented, then define "object-oriented" in a way that FILE can't fulfill.

jalf
I don't see that FILE can be derived from in any reasonable sense of the word derived. A FILE is not a socket, a file is not a buffer, a file is not a stream. It may contain any of those elements, but that's would seem to be an example of composition rather polymorphism.Your overall point is taken though. There is no ANSI/ECMA stanard for 'object-oriented'. The best we can do is common usage, and we could spend all day arguing about that.
Charles E. Grant
i like your answer jalf. it's just what i would have said too. i always regarded FILE as being object oriented.
Johannes Schaub - litb
@Charles: I agree that it's hard to justify calling it inheritance or derivation, but it certainly is polymorphism, not composition. The behavior of the FILE object changes depending on which of the many implementations you're using.
jalf
A: 

C has the first half of object orientated. Encapsulation, ie you can have compound types like FILE* or structs but you can't inherit from them which is the second (although less important) half

Martin Beckett
A: 

There are different definitions of oo around. The one I find most useful is the following (inspired by Alan Kay):

  1. objects hold state (ie references to other objects)
  2. objects receive (and process) messages
  3. processing a message may result in
    • messages beeing sent to the object itself or other objects
    • a change in the object's state

This means you can program in an object-oriented way in any imperative programming language - even assembler. A purely functional language has no state variables, which makes oo impossible or at least awkward to implement (remember: LISP is not pure!); the same should go for purely declarative languages.

In C, message passing in most often implemented as function calls with a pointer to a struct holding the object's state as first argument, which is the case for the file handling api. Still, C as a language can't be classified as oo as it doesn't have syntactic support for this style of programming.

Also, some other definitions of oo include things like class-based inheritance (so what about prototypal languages?) and encapsulation - which aren't really essential in my opinion - but some of them can be implemented in C with some pointer- and casting magic.

Christoph
Could you apply your analysis to the FILE interface?
Roger Pate