Question

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?

Was it helpful?

Solution

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;
}

OTHER TIPS

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:

  1. C programming language was created in 1972, and was influenced by pure assembly language, so struct was supposed as "data-only" element

  2. 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

  3. 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top