Data Abstraction in C
Asked Answered
W

2

7

What I understood about data abstraction is hiding technical details from user and showing only necessary details. So data abstraction is an OOP feature. My question is: does C also support data abstraction?

If so, why is data abstraction an Object Oriented Programming language feature and not a procedural language feature?

If the answer to my question is no, then what about structures, enums in C? They also hide details from users.

Wehrle answered 6/10, 2013 at 13:36 Comment(5)
"Why is data abstraction an Object Oriented Programming language feature and not a procedural language feature?" - That's not the case.Wiedmann
Then why it is mentioned everywhere as OOP feature and not procedural language feature??Wehrle
You're concluding that all men are cats, but that's not the case. Data abstraction is a desirable thing. OOP is a programming style that provides data abstraction. You can achieve data abstraction in many different ways.Doley
On top of that, it's perfectly possible to write in an object-oriented style in C. It's just more verbose and noisy than it is in other languages.Doley
Give a look to GObject.Laylalayman
R
8

It's certainly possible to do object oriented programming in C. Remember that e.g. the first C++ compiler was actually a C++ to C transpiler, the Python VM is written in C etc. The thing that sets so called OOP languages apart from other is better support for these constructs, for instance in syntax.

One common way to provide abstraction is function pointers. Look at the struct from the Linux kernel source below (from include/linux/virtio.h).

/**
 * virtio_driver - operations for a virtio I/O driver
 * @driver: underlying device driver (populate name and owner).
 * @id_table: the ids serviced by this driver.
 * @feature_table: an array of feature numbers supported by this driver.
 * @feature_table_size: number of entries in the feature table array.
 * @probe: the function to call when a device is found.  Returns 0 or -errno.
 * @remove: the function to call when a device is removed.
 * @config_changed: optional function to call when the device configuration
 *    changes; may be called in interrupt context.
 */
struct virtio_driver {
        struct device_driver driver;
        const struct virtio_device_id *id_table;
        const unsigned int *feature_table;
        unsigned int feature_table_size;
        int (*probe)(struct virtio_device *dev);
        void (*scan)(struct virtio_device *dev);
        void (*remove)(struct virtio_device *dev);
        void (*config_changed)(struct virtio_device *dev);
#ifdef CONFIG_PM
        int (*freeze)(struct virtio_device *dev);
        int (*restore)(struct virtio_device *dev);
#endif
};

probe, scan, remove etcetera are all function pointers that an I/O driver sets themselves. The kernel can then call these functions for any I/O driver without the need to know anything about the device. This is an example of abstraction in C. See this article to read more about this particular example.

Another form of data abstraction is opaque pointers. An opaque data type is declared in a header file, but the definition is never exposed. Code that doesn't know the definition of the type can never access it's value, only use pointers to it. See Opaque data type and Opaque pointer on Wikipedia.

An example of an opaque data type you've probably encountered is FILE from stdio.h. The same interface is used on all operating systems, although the actual data a FILE * points to is different. You can get a FILE * by calling fopen and manipulate it with a range of other function calls, but you may not see the data it points to.

To learn more about object oriented programming in C I recommend the free online book Object Oriented Programming in ANSI-C. Check out this Dr Dobbs article. Related questions: Object orientation in C and Can you write object oriented code in C?.

Rocco answered 22/7, 2015 at 14:35 Comment(0)
E
1

Hiding is easy in C, just a matter of cast.

OOP may be done but I would say that some feature isn't really handy to obtain (eg: inheritance) I guess polymorphism maybe even achieved but never tried at home!

C interfaces to native C++ libraries are common, something like:

void *obj_create(void); /* return obscure ptr */
int obj_method(void *obj, int somearg);
void obj_destroy(void *obj);

Separating the private headers from the public distributed and that is.

edit

In the AmigaOS there's a C basic OOP implementation that is working from years, still used from the AROS project at least, the implementation is called BOOPSI and is also the foundation for some of the GUI gadget (widget) but can be used just to describe objects, here a small introduction (In the Amiga Rom Kernel Reference Manual it is shown how to use it to broadcast a signal to more objects, a pioneer Qt's slots/signals implementation).

I been looking into Nim lang in the past days, it generate C code (add some runtime, which may be disabled) to compile with backends like gcc/clang/tinycc, and it support some OOP.

Engulf answered 6/10, 2013 at 14:32 Comment(1)
Another more obvious form of data hiding is declaring a struct with the extern keyword in a header but then defining that strict in a module. Only the functions in that module know the structure of the struct, but functions in other modules may still use a copy of that struct.Gause

© 2022 - 2024 — McMap. All rights reserved.