Related
I read plenty of questions regarding
declaration of functions inside structure?
But I did not get a satisfactory answer.
My question is not about whether functions can be declared inside a structure or not?
Instead, my question is
WHY function can not be declared inside structure?
Well that is the fundamental difference between C and C++ (works in C++). C++ supports classes (and in C++ a struct is a special case of a class), and C does not.
In C you would implement the class as a structure with functions that take a this pointer explicitly, which is essentially what C++ does under the hood. Coupled with a sensible naming convention so you know what functions belong to which classes (again something C++ does under then hood with name-mangling), you get close to object-based if not object-oriented programming. For example:
typedef struct temp
{
int a;
} classTemp ;
void classTemp_GetData( classTemp* pThis )
{
printf( "Enter value of a : " );
scanf( "%d", &(pThis->a) );
}
classTemp T ;
int main()
{
classTemp_GetData( &T );
}
However, as you can see without language support for classes, implementing then can become tiresome.
In C, the functions and data structures are more or less bare; the language gives a minimum of support for combining data structures together, and none at all (directly) for including functions with those data structures.
The purpose of C is to have a language that translates as directly as possible into machine code, more like a portable assembly language than a higher-level language such as C++ (not that C++ is all that high-level). C let's you get very close to the machine, getting into details that most languages abstract away; the down side of this is that you have to get close to the machine in C to use the language to its utmost. It takes a completely different approach to programming from C++, something that the surface similarities between them hide.
Check out here for more info (wonderful discussions there).
P.S.: You can also accomplish the functionality by using function pointers, i.e.
have a pointer to a function (as a variable) inside the struct.
For example:
#include <stdio.h>
struct t {
int a;
void (*fun) (int * a); // <-- function pointers
} ;
void get_a (int * a) {
printf (" input : ");
scanf ("%d", a);
}
int main () {
struct t test;
test.a = 0;
printf ("a (before): %d\n", test.a);
test.fun = get_a;
test.fun(&test.a);
printf ("a (after ): %d\n", test.a);
return 0;
}
WHY function can not be declared inside structure?
Because C standard does not allow to declare function/method inside a structure. C is not object-oriented language.
6.7.2.1 Structure and union specifiers:
A structure or union shall not contain a member with incomplete or function type(hence,
a structure shall not contain an instance of itself, but may contain a pointer to an instance
of itself), except that the last member of a structure with more than one named member
may have incomplete array type; such a structure (and any union containing, possibly
recursively, a member that is such a structure) shall not be a member of a structure or an
element of an array.
I suppose there were and are many reasons, here are several of them:
C programming language was created in 1972, and was influenced by pure assembly language, so struct was supposed as "data-only" element
As soon as C is NOT object oriented language - there is actually no sense to define functions inside "data structure", there are no such entity as constructor/method etc
Functions are directly translated to pure assembly push and call instructions and there are no hidden arguments like this
I guess, because it wouldn't make much sence in C. If you declare a function inside structure, you expect it to be somehow related to that structure, right? Say,
struct A {
int foo;
void hello() {
// smth
}
}
Would you expect hello() to have access to foo at least? Because otherwise hello() only got something like namespace, so to call it we would write A.hello() - it would be a static function, in terms of C++ - not much difference from normal C function.
If hello() has access to foo, there must be a this pointer to implement such access, which in C++ always implicitly passed to functions as first argument.
If a structure function has access to structure variables, it must be different somehow from access that have other functions, again, to add some sence to functions inside structures at all. So we have public, private modificators.
Next. You don't have inheritance in C (but you can simulate it), and this is something that adds lots of sence to declaring functions inside structutes. So here we'd like to add virtual and protected.
Now you can add namespaces and classes, and here you are, invented C++ (well, without templates).
But C++ is object-oriented, and C is not. First, people created C, then they wrote tons of programs, understood some improvements that could be made, and then, following reasonings that I mentioned earlier, they came up with C++. They did not change C instead to separate concepts - C is procedure-oriented, and C++ is object-oriented.
C was designed so that it could be processed with a relatively simple compilation system. To allow function definitions to appear within anything else would have required the compiler to keep track of the context in which the function appeared while processing it. Given that members of a structure, union, or enum declaration do not enter scope until the end of the declaration, there would be nothing that a function declared within a structure could do which a function declared elsewhere could not.
Conceptually, it might have been nice to allow constant declarations within a structure; a constant pointer to a literal function would then be a special case of that (even if the function itself had to be declared elsewhere), but that would have required the C compiler to keep track of more information for each structure member--not just its type and its offset, but also whether it was a constant and, if so, what its value should be. Such a thing would not be difficult in today's compilation environments, but early C compilers were expected to run with orders of magnitude less memory than would be available today.
Given that C has been extended to offer many features which could not very well be handled by a compiler running on a 64K (or smaller) system, it might reasonably be argued that it should no longer be bound by such constraints. Indeed, there are some aspect of C's heritage which I would like to lose, such as the integer-promotion rules which require even new integer types to follow the inconsistent rules for old types, rather than allowing the new types to have explicitly specified behavior [e.g. have a wrap32_t which could be converted to any other integer type without a typecast, but when added to any "non-wrap" integer type of any size would yield a wrap32_t]. Being able to define functions within a struct might be nice, but it would be pretty far down on my list of improvements.
Today, I have just noticed a statement in a C struct, and to be honest I was like WTF at first. It is like;
struct foo {
void *private;
//Some other members
};
Believe or not this struct is being compiled without any error. So what is the purpose of adding such a line (void *private)?
In pure C there's no private keyword, so the above is perfectly legal, albeit a very bad idea.
This would be invalid C++ though, and a C++ compiler would surely yield an error.
void* are in C often used to hide the actual data type used, effectively hiding some implementation details from the interface.
Actually you have stumbled upon an important difference between C and C++, the way structures are implemented.
In C, structures contains can contain only primitive and composite datatypes, whereas C++ structures gives more functionality, since the structures in C++ are similar to classes than structures in C, hence they provide additional functionality such as
Ability to classify members as private,public or protected.
Can contain member functions.
Structures in C++, can be used as a tool to enforce object oriented methods, since all OO functionality like inheritance, which is applicable to classes , holds good for structures as well.
So in short, the above code is valid C, but invalid C++.
Okay, you may call me a noob but I'm realling confused.
My ex classmate paid me to write a program in C. She gave me the task and it said something like "blah blah blah make at least TWO CLASSES, write at least ONE CONSTRUCTOR and rewrite at least ONE METHOD" it says that word by word.
And then I told her "this is C++ not C" she said "but we're learning C"
I ignored it and wrote the program in c++ and sent to her as I thought she didn't know what she was talking about. She said "it doesn't work on code blocks, and wtf is cout <<" and then she sent me a chunk of code that they write and instead of cout and cin there was printf and scanf. It had to be C. So, I rewrote the program with printf and scanf and she still says codeblocks throw errors (I still left classes as task demanded).
I want to ask wtf? Does C have classes? Or is there a misunderstanding or something?
EDIT: I've come back to the question after so many years and noticed some a*****es took time to remove 99% text from the question. Get a life, this is not 1984 yet.
No, C doesn't have classes. That said, there are ways of simulating object-oriented programming in C - a quick Google search should yield some useful results.
No, C has no classes per se, only C++ (which started out as "C with classes" back then...). But you can use the standard C library in C++ code, even if it is often not considered good practice (where C++ has its own, higher level constructs, e.g. cout vs printf).
You can sort of emulate the behaviour of classes, inheritance and virtual functions in C too, but it's not worth the pain.
You should probably buy/get your ex classmate a C programming book :-)
C does not have the formal construct of a class. You can produce modules with module-level data that by your own agreement you will not extern anywhere else, or static data, and write functions to get, set, and otherwise manipulate that data. You can even go to the point of using function pointers to manipulate similar data types as if they were in a class.
However, you won't be protected by class semantics or other rules by the C compiler, because the C compiler does not know about classes. However, structuring your data is quite powerful.
C does not have classes.
But one can approximate a class by using static globals as private class members, and static functions as private member functions. extern members as public. In this case an entire file could be viewed as a class.
Probably this is not what you want.
A classic case of conflicting requirements, it seems :-)
The terminology of her requirements CLASS, CONSTRUCTOR, METHOD are all C++ terminology, while none of them is C terminology (the closest of which would arguably be STRUCT, INITIALIZATION, FUNCTION). Your friend is confusing something here. I doubt that her teacher is confusing something, though...
C does not have classes, but you can emulate it with structures and pointers to a function. C99 is a little bit (just a bit) based on C++, so it's easy to reproduce classes with C.
C doesn't support classes, but we do have tricky hacky workaround. Read entire explanation or simply scroll down to code section.
struct declaration:
I declared an struct with name class. Inside, I put uninitialized function with type void, name Print and one parameter char.
This will look like void class.Print(char);
struct don't allow initialization inside:
But struct doesn't allow initialization of variables inside. So we will init it outside. We created an a function with type of class, name Printer. It inits that struct and return initialized struct which we can easily make use of.
call the class:
Now we included helper header and declared variable with type class, name printer1, value Printer(). After I called member of class and print string using printer1.Print("Hello from class function");
main.c
#include "helper.h"
void main()
{
class printer1 = Printer();
printer1.Print("Hello from class function");
}
helper.h
#include <stdio.h> //imports int printf(...);
void print(const char* text)
{
printf(text);
}
typedef struct
{
void (*Print) (const char*);
} class;
class Printer()
{
class Printer;
Printer.Print = &print;
return Printer;
}
Note:
This exact example was compiled and tested successfully with VC and tcc compiler.
class is example name. You can use any other name as well.
C mostly uses functional/structural programming instead of implementing Object Oriented Programming as in languages like C++ , Java , Python etc. which use classes . But in few instances we use classes like in:
typedef struct {
ShapeClass shape;
float width, height;
}
RectangleClass;
Hope it helped.
This question already has answers here:
Object Oriented pattern in C? [duplicate]
(4 answers)
Closed 1 year ago.
Possible Duplicates:
Can you write object oriented code in C?
Object Oriented pattern in C ?
I remember reading a while ago about someone (I think it was Linus Torvalds) talking about how C++ is a horrible language and how you can write object-oriented programs with C. On having had time to reflect, I don't really see how all object oriented concepts carry over into C. Some things are fairly obvious. For example:
To emulate member functions, you can put function pointers in structs.
To emulate polymorphism, you can write a function that takes a variable number of arguments and do some voodoo depending on, say, the sizeof the parameter(s)
How would you emulate encapsulation and inheritance though?
I suppose encapsulation could sort of be emulated by having a nested struct that stored private members. It would be fairly easy to get around, but could perhaps be named PRIVATE or something equally obvious to signal that it isn't meant to be used from outside the struct. What about inheritance though?
You can implement polymorphism with regular functions and virtual tables (vtables). Here's a pretty neat system that I invented (based on C++) for a programming exercise:
The constructors allocate memory and then call the class's init function where the memory is initialized. Each init function should also contain a static vtable struct that contains the virtual function pointers (NULL for pure virtual). Derived class init functions call the superclass init function before doing anything else.
A very nice API can be created by implementing the virtual function wrappers (not to be confused with the functions pointed to by the vtables) as follows (add static inline in front of it, if you do this in the header):
int playerGuess(Player* this) { return this->vtable->guess(this); }
Single inheritance can be done by abusing the binary layout of a struct:
Notice that multiple inheritance is messier as then you often need to adjust the pointer value when casting between types of the hierarchy.
Other type-specific data can be added to the virtual tables as well. Examples include runtime type info (e.g. type name as a string), linking to superclass vtable and the destructor chain. You probably want virtual destructors where derived class destructor demotes the object to its super class and then recursively calls the destructor of that and so on, until the base class destructor is reached and that finally frees the struct.
Encapsulation was done by defining the structs in player_protected.h and implementing the functions (pointed to by the vtable) in player_protected.c, and similarly for derived classes, but this is quite clumsy and it degrades performance (as virtual wrappers cannot be put to headers), so I would recommend against it.
Have you read the "bible" on the subject? See Object Oriented C...
How would you emulate encapsulation and inheritance though?
Actually, encapsulation is the easiest part. Encapsulation is a design philosophy, it has nothing at all to do with the language and everything to to with how you think about problems.
For example, the Windows FILE api is completely encapsulated. When you open a file, you get back an opaque object that contains all of the state information for the file 'object'. You hand this handle back to each of the file io apis. The encapsulation is actually much better than C++ because there is no public header file that people can look at and see the names of your private variables.
Inheritance is harder, but it isn't at all necessary in order for your code to be object oriented. In some ways aggregation is better than inheritance anyway, and aggregation is just as easy in C as in C++. see this for instance.
In response to Neil see Wikipedia for an explanation of why inheritance isn't necessary for polymorphism.
Us old-timers wrote object oriented code years before C++ compilers were available, it's a mind-set not a tool-set.
Apple's C-based CoreFoundation framework was actually written so that its "objects" could double as objects in Objective-C, an actual OO language. A fairly large subset of the framework is open source on Apple's site as CF-Lite. Might be a useful case study in a major OS-level framework done this way.
From a little bit higher altitude and considering the problem rather more open-minded than as the OOP mainstream may suggest, Object-Oriented Programming means thinking about objects as of data with associated functions. It does not necessarily mean an function has to be physically attached to an object as it is in popular languages which support paradigm of OOP, for instance in C++:
struct T
{
int data;
int get_data() const { return data; }
};
I would suggest to take a closer look at GTK+ Object and Type System. It is a brilliant example of OOP realised in C programming language:
GTK+ implements its own custom object
system, which offers standard
object-oriented features such as
inheritance and virtual function
The association can also be contractual and conventional.
Regarding encapsulation and data hiding techniques, popular and simple one may be Opaque Pointer (or Opaque Data Type) - you can pass it around but in order to load or store any information, you have to call associated function which knows how to talk to the object hidden behind that opaque pointer.
Another one, similar but different is Shadow Data type - check this link where Jon Jagger gives excellent explanation of this not-so-well-known-technique.
the gtk and glib libraries use macros to cast objects to various types.
add_widget(GTK_WIDGET(myButton));
I can't say how it's done but you can read their source to find out exactly how it's done.
Take a look at the way the VFS layer works in the Linux kernel for an example of an inheritance pattern. The file operations for the various filesystems "inherit" a set of generic file operations functions (eg generic_file_aio_read(), generic_file_llseek()...), but can override them with their own implementations (eg. ntfs_file_aio_write()).
Definitely look at Objective-C.
typedef struct objc_object {
Class isa;
} *id;
typedef struct objc_class {
struct objc_class *isa;
struct objc_class *super_class
const char *name;
long version;
long info
long instance_size;
struct objc_ivar_list *ivars;
struct objc_method_list **methodLists;
struct objc_cache *cache;
struct objc_protocol_list *protocols;
} *Class;
As you can see, inheritance information, along with other details is held in a class struct (conveniently the class can also be treated as an object).
Objective-C suffers in the same manner as C++ with encapsulation in that you need to declare your variables publicly. Straight C is much more flexible in that you can just return void pointers that only your module has internal access to, so in that respect encapsulation is much better.
I once wrote a basic OO style C paint program as part of a graphics course - I didn't go as far as the class declaration, I simply used a vtable pointer as the first element of the struct and implemented hand-coded inheritance. The neat thing about playing around with vtables at such a low level is that you can change class behaviour at runtime by changing a few pointers, or change on objects class dynamically. It was quite easy to create all sorts of hybrid objects, fake multiple inheritance, etc.
Nice article & discussion regarding Objective-C here:
http://cocoawithlove.com/2009/10/objective-c-niche-why-it-survives-in.html
For a great example of object-oriented programming in C, look at the source of POV-Ray from several years ago - version 3.1g is particularly good. "Objects" were struct with function pointers, of course. Macros were used to provide the core methods and data for an abstract object, and derived classes were structs that began with that macro. There was no attempt to deal with private/public, however. Things to be seen were in .h files and implementation details were in .c files, mostly, except for a lot of exceptions.
There were some neat tricks that I don't see how could be carried over to C++ - such as converting one class to a different but similar one on the fly just by reassigning function pointers. Simple for today's dynamic languages. I forgot the details; I think it might have been CSG intersection and union objects.
http://www.povray.org/
An interesting bit of history. Cfront, the original C++ implementation output C code and then requires a C compiler to actually build the final code. So, anything that could be expressed in C++ could be written as C.
One way to handle inheritance is by having nested structs:
struct base
{
...
};
void method_of_base(base *b, ...);
struct child
{
struct base base_elements;
...
};
You can then do calls like this:
struct child c;
method_of_base(&c.b, ...);
You might want to look at Objective-C, that's pretty much what it does. It's just a front-end that compiles Objective-C OO code to C.
Coming from OO (C#, Java, Scala) I value very highly the principles of both code reuse and type-safety. Type arguments in the above languages do the job and enable generic data structures which are both type-safe and don't 'waste' code.
As I get stuck into C, I'm aware that I have to make a compromise and I'd like it to be the right one. Either my data structures have a void * in each node / element and I lose type safety or I have to re-write my structures and code for each type I want to use them with.
The complexity of the code is an obvious factor: iterating through an array or a linked-list is trivial and adding a *next to a struct is no extra effort; in these cases it makes sense not to try and re-use structures and code. But for more complicated structures the answer isn't so obvious.
There's also modularity and testability: separating out the type and its operations from the code that uses the structure makes testing it easier. The inverse is also true: testing the iteration of some code over a structure whilst it's trying to do other things gets messy.
So what's your advice? void * and reuse or type-safety and duplicated code? Are there any general principles? Am I trying to force OO onto procedural when it won't fit?
Edit: Please don't recommend C++, my question is about C!
I would say use void * so you can re-use the code. It's more work to re-implement e.g. a linked list, than to make sure you get/set the data in the list properly.
Take as many hints from glib as possible, I find their data structures very nice and easy to use, and have had little trouble because of the loss of type safety.
I think you'll have to strike a balance between the two, just as you suggest. If the code is only a few lines and trivial I would duplicate it but if it's more complex, I would consider working with void* to avoid having to do any potential bug fixing and maintenance in several places and also to reduce the code size.
If you look at the C runtime library, there's several "generic" functions that work with void*, one common example is sorting with qsort. It would be madness to duplicate this code for every type you'd like to sort.
There's nothing wrong with using void pointers. You don't even have to cast them when assigning them to a variable of type of pointer since the conversion is done internally. It migtht be worth having a look at this: http://www.cpax.org.uk/prg/writings/casting.php
The answer this question is the same as getting efficient templates for link list in C++.
a) Create an abstract version of the algorithm that uses void* or some Abstracted Type
b) Create a light weight public interface to call the Abstracted Type algorithms and caste between them.
For example.
typedef struct simple_list
{
struct simple_list* next;
} SimpleList;
void add_to_list( SimpleList* listTop, SimpleList* element );
SimpleList* get_from_top( SimpleList* listTop );
// the rest
#define ListType(x) \
void add_ ## x ( x* l, x* e ) \
{ add_to_list( (SimpleList*)l, (SimpleList*)x ); } \
void get_ ## x ( x* l, x* e ) \
{ return (x*) get_from_to( (SimpleList*)l ); } \
/* the rest */
typedef struct my_struct
{
struct my_struct* next;
/* rest of my stuff */
} MyStruct;
ListType(MyStruct)
MyStruct a;
MyStruct b;
add_MyStruct( &a, &b );
MyStruct* c = get_MyStruct(&a);
etc etc.
We use OO in C a lot here, but only for encapsulation and abstraction, no polymorphism or so.
Which means we have specific types, like FooBar(Foo a, ...) but, for our collection "classes", we use void *. Just use void * where multiple types could be used, BUT, by doing so, ensure you don't need the argument to be of a specific type. As per collection, having void * is alright, because the collection doesn't care about the type. But if your function can accept type a and type b but none other, make two variants, one for a and one for b.
The main point is to use a void * only when you don't care about the type.
Now, if you have 50 types with the same base structure (let's say, int a; int b; as first members of all types), and want a function to act upon those types, just make the common first members a type by itself, then make the function accept this, and pass object->ab or (AB*)object is your type is opaque, both will work if ab is the first field in your struct.
You can use macros, they will work with any type and the compiler will check statically the expanded code. The downside is that the code density (in the binary) will worsen and they are more difficult to debug.
I asked this question about generic functions some time ago and the answers could help you.
You can efficiently add type information, inheritance and polymorphism to C data structures, that's what C++ does. (http://www.embedded.com/97/fe29712.htm)
Definitely generic void*, never duplicate code!
Take into account that this dilemma was considered by many a C programmer, and many major C projects. All serious C projects I've ever encountered, whether open-source or commercial, picked the generic void*. When used carefully and wrapped into a good API, it is barely a burden on the user of the library. Moreover, void* is idiomatic C, recommended directly in K&R2. It is the way people expect code to be written, and anything else would be surprising and badly accepted.
You can build a (sort of) OO framework using C, but you miss out on a lot of the benefits ... like an OO type system that the compiler understands. If you insist on doing OO in a C-like language, C++ is a better choice. It is more complicated than vanilla C, but at least you get proper linguistic support for OO.
EDIT: Ok ... if you insist that we don't recommend C++, I recommend that you don't do OO in C. Happy? As far as your OO habits are concerned, you should probably think in terms of "objects", but leave inheritance and polymorphism out of your implementation strategy. Genericity (using function pointers) should be used sparingly.
EDIT 2: Actually, I think that use of void * in a generic C list is reasonable. It is just trying to build an mock OO framework using macros, function pointers, dispatching and that kind of nonsense that I think is a bad idea.
In Java all collections from java.util package in effect hold equivalent of void* pointer ( the Object ).
Yes, generics ( introduced in 1.5 ) add syntactic sugar and prevent you from coding unsafe assignments, however the storage type remains Object.
So, I think there is no OO crime commited when you use void* for generic framework type.
I would also add type-specific inlines or macro wrappers that assign/retrieve data from the generic structures if you do this often in your code.
P.S. The one thing that you should NOT do is to use void** to return allocated/reallocated generic types. If you check the signatures of malloc/realloc you will see that you can achieve correct memory allocations without dreaded void** pointer. I am only telling this because I've seen this in some open-source project, that I do not wish to name here.
A generic container can be wrapped with a little work so that it can be instantiated in type-safe versions. Here is an example, full headers linked below:
/* generic implementation */
struct deque *deque_next(struct deque *dq);
void *deque_value(const struct deque *dq);
/* Prepend a node carrying `value` to the deque `dq` which may
* be NULL, in which case a new deque is created.
* O(1)
*/
void deque_prepend(struct deque **dq, void *value);
From the header that can be used to instantiate specific wrapped types of deque
#include "deque.h"
#ifndef DEQUE_TAG
#error "Must define DEQUE_TAG to use this header file"
#ifndef DEQUE_VALUE_TYPE
#error "Must define DEQUE_VALUE_TYPE to use this header file"
#endif
#else
#define DEQUE_GEN_PASTE_(x,y) x ## y
#define DEQUE_GEN_PASTE(x,y) DEQUE_GEN_PASTE_(x,y)
#define DQTAG(suffix) DEQUE_GEN_PASTE(DEQUE_TAG,suffix)
#define DQVALUE DEQUE_VALUE_TYPE
#define DQREF DQTAG(_ref_t)
typedef struct {
deque_t *dq;
} DQREF;
static inline DQREF DQTAG(_next) (DQREF ref) {
return (DQREF){deque_next(ref.dq)};
}
static inline DQVALUE DQTAG(_value) (DQREF ref) {
return deque_value(ref.dq);
}
static inline void DQTAG(_prepend) (DQREF *ref, DQVALUE val) {
deque_prepend(&ref->dq, val);
}
deque.h: http://ideone.com/eDNBN
deque_gen.h: http://ideone.com/IkJRq