Can structures contain functions?
No, but they can contain function pointers.
If your intent is to do some form of polymorphism in C then yes, it can be done:
typedef struct {
int (*open)(void *self, char *fspec);
int (*close)(void *self);
int (*read)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
int (*write)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
// And data goes here.
} tCommClass;
The typedef above was for a structure I created for a general purpose communications library. In order to initialise the variable, you would:
tCommClass *makeCommTcp (void) {
tCommClass *comm = malloc (sizeof (tCommClass));
if (comm != NULL) {
comm->open = &tcpOpen;
comm->close = &tcpOpen;
comm->read = &tcpOpen;
comm->write = &tcpWrite;
}
return comm;
}
tCommClass *makeCommSna (void) {
tCommClass *comm = malloc (sizeof (tCommClass));
if (comm != NULL) {
comm->open = &snaOpen;
comm->close = &snaOpen;
comm->read = &snaOpen;
comm->write = &snaWrite;
}
return comm;
}
tCommClass *commTcp = makeCommTcp();
tCommClass *commSna = makeCommSna();
Then, to call the functions, something like:
// Pass commTcp as first params so we have a self/this variable
// for accessing other functions and data area of object.
int stat = (commTcp->open)(commTcp, "bigiron.box.com:5000");
In this way, a single type could be used for TCP, SNA, RS232 or even carrier pidgeons, with exactly the same interface.
edit Cleared up ambiguity with the use of 'data types'
Not in C. struct types can only contain data.
From Section 6.7.2.1 of the ISO C99 Standard.
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.
No, you cannot. A structure cannot contain a declaration of a function but they can contain a definition of a function. A structure can only contain data types, pointers, pointers to different function. You can make a pointer to a function and then access from the structure.
#include<iostream>
#include<cstring>
using namespace std;
struct full_name
{
char *fname;
char *lname;
void (*show)(char *,char*);
};
void show(char *a1,char * a2)
{
cout<<a1<<"-"<<a2<<endl;
}
int main()
{
struct full_name loki;
loki.fname="Mohit";
loki.lname="Dabas";
loki.show=show;
loki.show(loki.fname,loki.lname);
return 0;
}
In C, structures are allowed to contain on data values and not the function pointers. Not allowed in C. but the following works literally fine when checked with gcc.
enter code here
#include <stdio.h>
struct st_func_ptr{
int data;
int (*callback) ();
};
int cb(){
printf(" Inside the call back \n");
return 0;
}
int main() {
struct st_func_ptr sfp = {10, cb};
printf("return value = %d \n",sfp.callback());
printf(" Inside main\n");
return 0;
}
So, am confused ...
It's all right.
In the linux kernel code,you will find many structures contain functions.
such as:
/*
* The type of device, "struct device" is embedded in. A class
* or bus can contain devices of different types
* like "partitions" and "disks", "mouse" and "event".
* This identifies the device type and carries type-specific
* information, equivalent to the kobj_type of a kobject.
* If "name" is specified, the uevent will contain it in
* the DEVTYPE variable.
*/
struct device_type {
const char *name;
struct attribute_group **groups;
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
void (*release)(struct device *dev);
int (*suspend)(struct device * dev, pm_message_t state);
int (*resume)(struct device * dev);
};
Yes its possible to declare a function and the function definition is not allowed and that should be the function pointer.
Its based on C99 tagged structure.
Lokesh V
They can, but there is no inherent advantage in usual C programming.
In C, all functions are in the global space anyway, so you get no information hiding by tucking them in a function. paxdiablo 's example is a way to organize functions into a struct, but you must see has to dereference each one anyway to use it.
The standard organizational structure of C is the File, with
the interfaces in the header and the implementations in the source.
That is how libc is done and that is how almost all C libraries are done.
Moder C compilers allow you to define and implement functions in the same source file, and even implement static functions in header files. This unfortunately leads to some confusion as to what goes where, and you can get unusual solutions like cramming functions into structs, source-only programs with no headers, etc.
You lose the advantage of separating interface from implementation that way.
Related
I have the following in C (not C++!):
module.c
struct Private {...};
void foo(void* private, int param) {...}
module.h
#define PRIVATE_SIZE ???;
void foo(void* private, int param);
main.c
char m1[PRIVATE_SIZE];
char m2[PRIVATE_SIZE];
int main()
{
foo(m1, 10);
foo(m2, 20);
}
How can I expose sizeof(Private) at compile time so that application can statically allocate its storage without exposing Private type?
Note, this is a very limited embedded system and dynamic allocation is not available.
You shouldn't expose the size of the struct to the caller, because that breaks the whole purpose of having private encapsulation in the first place. Allocation of your private data is no business of the caller. Also, avoid using void* because they complete lack type safety.
This is how you write private encapsulation in C:
In module.h, forward declare an incomplete type typedef struct module module;.
In module.c, place the struct definition of this struct. it will only be visible to module.c and not to the caller. This is known as opaque types.
The caller can only allocate pointers to this struct, never allocate objects.
Caller code might look like:
#include "module.h"
...
module* m;
result = module_init(&m)
And the module_init function acts as a "constructor", declared in module.h and defined in module.c:
bool module_init (module** obj)
{
module* m = malloc(sizeof *m);
...
m->something = ...; // init private variables if applicable
*obj = m;
return true;
}
If the caller does need to know the size of the objects, it would only be for the purpose of hard copy etc. If there's a need for that, provide a copy function which encapsulates the allocation and copy ("copy constructor"), for example:
result module_copy (module** dst, const module* src);
Edit:
Please note that the manner of allocation is a separate issue. You don't have to use dynamic allocation for the above design. In embedded systems for example, it is common to use static memory pools instead. See Static allocation of opaque data types
You can't allocate size for a struct such as this because it isn't known at compile time. Even if you did know the size at run time, you'd still have issues due to alignment.
There is a possible solution which involves defining a separate structure that has the same size and alignment requirements as the private struct.
For example:
module.h:
#include <inttypes.h>
struct Public {
uint64_t opaque1;
uint64_t opaque2;
uint64_t opaque3;
};
void init(struct Public *p);
module.c:
#include <assert.h>
#include <stdalign.h>
#include "module.h"
struct Private {
int a;
double b;
float c;
};
static_assert(sizeof(struct Private)==sizeof(struct Public), "sizes differ");
static_assert(alignof(struct Private)==alignof(struct Public), "alignments differ");
void init(struct Public *p)
{
struct Private *pr = (struct Private *)p;
pr->a = 2;
pr->b = 2.5;
pr->c = 2.4f;
}
The Public and Private structs are guaranteed to have the same size, and the alignment should be the same. There is the possibility of the user writing the the "opaque" fields of the public struct, in which case you could have aliasing issues regarding effective types, but if the user can be trusted to do that then this should work.
Another, more robust option, is if you have some idea of the maximum number of objects you want to support. If that's the case, you can have a static array of these objects in your implementation file, and the init function would return a pointer to one of the objects in this list. Then you'd have a related cleanup function that would free the instance.
For example:
module.c:
struct Private {
int a;
double b;
float c;
};
struct PrivateAllocator {
struct Private obj;
int used;
};
struct PrivateAllocator list[5] = {
{ { 0, 0, 0}, 0 },
{ { 0, 0, 0}, 0 },
{ { 0, 0, 0}, 0 },
{ { 0, 0, 0}, 0 },
{ { 0, 0, 0}, 0 }
};
struct Private *private_init()
{
int i;
for (i=0; i<5; i++) {
if (!list[i].used) {
list[i].used = 1;
return &list[i].obj;
}
}
return NULL;
}
void private_free(struct Private *p)
{
int i;
for (i=0; i<5; i++) {
if (&list[i].obj == p) {
list[i].used = 0;
return;
}
}
}
In conforming C code you can't create a static instance of an arbitrary unknown type even if you know its size at compile time (not even if you know the alignment).
Let's say you try doing it anyway. How would you do it, given the size in a macro or enum PRIVATE_SIZE?
unsigned char obj[PRIVATE_SIZE];
And then you'd pass (void*)obj to wherever its needed, right?
Well, this breaks the aliasing rules. While you can legally access any individual char/byte in any object, you can't do it the other way around saying that those chars are not chars, they are just storage behind other types. That is, you can't legally have a short int superimposed on top of, say, obj[2] and obj[3] through smarty-pants casts (e.g. ((struct Private*)obj)->my_short = 2;). The only legal way to do something like this would be through memcpy(), e.g. memcpy(&temp, obj, sizeof temp); and then back after the modification. Or you'd need to work with individual chars of obj[].
There are two possible ways to sort of do it. One is described in another answer, basically define the instance where the type is known, but only let the outside world have a pointer to it.
Another, very similar, define it in assembly code and, again, let the outside world have a pointer to it. The "beauty" of the assembly way is that you really only need a name, an alignment and a size to allocate space for a named object.
And if you put the instances into a special data section (see the gcc's section attribute and the linker scripts), you may even have all of the instances in the same place (think, array) and even find out their cumulative size and therefore count.
Yet another thing to do while not explicitly violating any C rules is to still use this unsigned char obj[PRIVATE_SIZE] trick, but launder it by passing it unchanged through an assembly function that the C compiler can't look into, e.g. something like
// struct Private* launder(unsigned char*);
.text
.globl launder
launder:
move %first_param_reg, %return_reg
ret
But you'll really need to change unsigned char obj[PRIVATE_SIZE] to something that would have proper alignment on your architecture, e.g. double obj[PRIVATE_SIZE / sizeof(double)] (or the same with long long if you like that way better).
As for PRIVATE_SIZE, you can have a check at compile time that it matches the size of the type, e.g.
#include "mod.h" // mod.h defines PRIVATE_SIZE
struct Private { ... };
extern char StAtIcAsSeRt[sizeof(struct Private) == PRIVATE_SIZE];
How to expose C struct size without exposing its type?
If able to compromise a bit: (statically --> main() local)
with variable length arrays (C99), use a helper function and put the array in main().
module.h
size_t foo_size(void);
main.c
int main() {
char m1[foo_size()];
foo(m1, 10);
}
Additional work needed to account for alignment issues.
Consider relaxing your goal as suggested.
C99 allowes you to use variable length array.
private.h:
#include <stdio.h>
extern const size_t size;
private.c:
#include "private.h"
struct Private {
int x;
int y;
int z;
};
const size_t size = sizeof(struct Private);
main.c:
#include <stdio.h>
#include "private.h"
int main(void) {
char m1[size]; //variable length array
printf("Size of m1 = %ld\n", sizeof(m1));
}
The question is based on a design pattern solution easily doable in other languages but difficult to implement in C. The narrowed down code is below.
Building on this answer, I'm trying to find a solution for the dynamically generated values in an anonymous function.
Excerpt from the answer:
int (*max)(int, int) =
({
int __fn__ (int x, int y) { return x > y ? x : y; }
__fn__;
});
Static Library Code
struct Super{
}
void add(struct Super *(*superRef)()) {
// cache the reference (in some linked list)
// later at some point when an event occurs.
struct Super *super = superRef(); // instantiate and use it.
}
Client Code linked: User of the Library Code
struct Sub{
struct Super *super;
}
add(({
struct Sub __fn__() { return malloc(sizeof(struct Sub)); } // error
__fn__;
}));
Error:
error: passing 'void' to parameter of incompatible type 'struct Sub *(*)()
As per the request for clarification, think of the receiving function in a static library file receiving references to the structure objects (non-instantiated). The lib receives this object from the client code.
Secondly the client or static library library doesn't instantiate the received structure reference right away. Later when there's a notification in the system, the structure reference is called to instantiate and execute the rest of the stuff.
I repeat, the specific requirement is to hold non-instantiated references to the structures passed by users of the library (client code).
Summary
Basically a Runner that receives pointer to a polymorphic factory method which it caches and later calls to instantiate and executes when an event occurs.
The correct order is:
learn C
do magic
It just will not work in the other way. ({}) does not bend the semantics for you. If your add expects a function which returns struct Super*, it will not work with struct Sub, not even if you put the missing * there.
This just works on TutorialsPoint:
#include <stdio.h>
#include <stdlib.h>
int max(int a,int b){
if(a>b)
return a;
return b;
}
struct Super{};
void add(struct Super *(*superRef)()) {
struct Super *(*secretStorage)()=superRef;
/* ... */
struct Super *super = secretStorage();
/* ... */
free(super);
printf("Stillalive\n");
}
int main()
{
printf("Hello, World!\n");
int (*myMax)(int,int); // <-- that is a function pointer
myMax=max; // <-- set with oldschool function
printf("%d\n",myMax(1,2));
myMax = ({ // <-- set with fancy magic
int __fn__ (int x, int y) { return x < y ? x : y; }
__fn__;
});
printf("%d - intentionally wrong\n",myMax(1,2));
add(
({
struct Super* fn(){
printf("Iamhere\n");
return malloc(sizeof(struct Super));
}
fn;}));
printf("Byfornow\n");
return 0;
}
Created a small library project with anonymous magic embedded in anonymous magic and heap allocation. It does not make much sense, but it works:
testlib.h
#ifndef TESTLIB_H_
#define TESTLIB_H_
struct Testruct{
const char *message;
void (*printmessage)(const char *message);
};
extern struct Testruct *(*nonsense())();
#endif
testlib.c
#include "testlib.h"
#include <stdio.h>
#include <stdlib.h>
const char *HELLO="Hello World\n";
struct Testruct *(*nonsense())(){
return ({
struct Testruct *magic(){
struct Testruct *retval=malloc(sizeof(struct Testruct));
retval->message=HELLO;
retval->printmessage=({
void magic(const char *message){
printf(message);
}
magic;
});
return retval;
}
magic;
});
}
test.c
#include "testlib.h"
#include <stdio.h>
#include <stdlib.h>
int main(){
struct Testruct *(*factory)()=nonsense();
printf("Alive\n");
struct Testruct *stuff=factory();
printf("Alive\n");
stuff->printmessage(stuff->message);
printf("Alive\n");
free(stuff);
printf("Alive\n");
return 0;
}
I followed the steps in https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html for building an running it (practically 3 gcc calls: gcc -c -Wall -Werror -fpic testlib.c, gcc -shared -o libtestlib.so testlib.o, gcc -L. -Wall -o test test.c -ltestlib and a bit of fight with LD_LIBRARY_PATH)
The code shown in the question is not standard C, but the GNU C variant that GCC supports. Unfortunately, there does not seem to be a gnu-c tag, to correctly specify the variant of C involved.
Furthermore, the use case seems to rely on shoehorning specific type of object-oriented paradigm into a C library interface. This is horrible, because it involves assumptions and features C simply does not have. There is a reason why C (and GNU-C) and C++ and Objective-C are different programming languages.
The simple answer to "functions returning dynamically allocated values" where the type of the value is opaque to the library, is to use void *, and for function pointers, (void *)(). Note that in POSIX C, void * can also hold a function pointer.
The more complex answer would describe how libraries like GObject support object-oriented paradigms in C.
In practice, especially in POSIX C, using a type tag (usually int, but can be any other type) and an union, one can implement polymorphic structures, based on an union of structures with all having that type tag as the same first element. The most common example of such functionality is struct sockaddr.
Basically, your header file defines one or more structures with the same initial member, for example
enum {
MYOBJECT_TYPE_DOUBLE,
MYOBJECT_TYPE_VOID_FUNCTION,
};
struct myobject_double {
int type; /* MYOBJECT_TYPE_DOUBLE */
double value;
};
struct myobject_void_function {
int type; /* MYOBJECT_TYPE_VOID_FUNCTION */
void (*value)();
};
and at the end, an union type, or a structure type with an anonymous union (as provided by C11 or GNU-C), of all the structure types,
struct myobject {
union {
struct { int type; }; /* for direct 'type' member access */
struct myobject_double as_double;
struct myobject_void_function as_void_function;
};
};
Note that technically, wherever that union is visible, it is valid to cast any pointer of any of those structure types to another of those structure types, and access the type member (see C11 6.5.2.3p6). It is not necessary to use the union at all, it suffices for the union to be defined and visible.
Still, for ease of maintenance (and to avoid arguments with language lawyer wannabes who did not read that paragraph in the C standard), I do recommend using the structure containing the anonymous union as the "base" type in the library interface.
For example, the library might provide a function to return the actual size of some object:
size_t myobject_size(struct myobject *obj)
{
if (obj)
switch (obj->type) {
case MYOBJECT_TYPE_DOUBLE: return sizeof (struct myobject_double);
case MYOBJECT_TYPE_VOID_FUNCTION: return sizeof (struct myobject_void_function);
}
errno = EINVAL;
return 0;
}
It seems to me OP is trying to implement a factory pattern, where the library function provides the specification (class in OOP) for the object created, and a method to produce those objects later.
The only way in C to implement dynamic typing is via the kind of polymorphism I show above. This means that the specification for the future objects (again, class in OOP) must be an ordinary object itself.
The factory pattern itself is pretty easy to implement in standard C. The library header file contains for example
#include <stdlib.h>
/*
* Generic, application-visible stuff
*/
struct any_factory {
/* Function to create an object */
void *(*produce)(struct any_factory *);
/* Function to discard this factory */
void (*retire)(struct any_factory *);
/* Flexible array member; the actual
size of this structure varies. */
unsigned long payload[];
};
static inline void *factory_produce(struct any_factory *factory)
{
if (factory && factory->produce)
return factory->produce(factory);
/* C has no exceptions, but does have thread-local 'errno'.
The error codes do vary from system to system. */
errno = EINVAL;
return NULL;
}
static inline void factory_retire(struct any_factory *factory)
{
if (factory) {
if (factory->retire) {
factory->retire(factory);
} else {
/* Optional: Poison function pointers, to easily
detect use-after-free bugs. */
factory->produce = NULL;
factory->retire = NULL; /* Already NULL, too. */
/* Free the factory object. */
free(factory);
}
}
}
/*
* Library function.
*
* This one takes a pointer and size in chars, and returns
* a factory object that produces dynamically allocated
* copies of the data.
*/
struct any_factory *mem_factory(const void *, const size_t);
where factory_produce() is a helper function which invokes the factory to produce one object, and factory_retire() retires (discards/frees) the factory itself. Aside from the extra error checking, factory_produce(factory) is equivalent to (factory)->produce(factory), and factory_retire(factory) to (factory)->retire(factory).
The mem_factory(ptr, len) function is an example of a factory function provided by a library. It creates a factory, that produces dynamically allocated copies of the data seen at the time of the mem_factory() call.
The library implementation itself would be something along the lines of
#include <stdlib.h>
#include <string.h>
#include <errno.h>
struct mem_factory {
void *(*produce)(struct any_factory *);
void (*retire)(struct any_factory *);
size_t size;
unsigned char data[];
};
/* The visibility of this union ensures the initial sequences
in the structures are compatible; see C11 6.5.2.3p6.
Essentially, this causes the casts between these structure
types, for accessing their initial common members, valid. */
union factory_union {
struct any_factory any;
struct mem_factory mem;
};
static void *mem_producer(struct any_factory *any)
{
if (any) {
struct mem_factory *mem = (struct mem_factory *)any;
/* We return a dynamically allocated copy of the data,
padded with 8 to 15 zeros.. for no reason. */
const size_t size = (mem->size | 7) + 9;
char *result;
result = malloc(size);
if (!result) {
errno = ENOMEM;
return NULL;
}
/* Clear the padding. */
memset(result + size - 16, 0, 16);
/* Copy the data, if any. */
if (mem->size)
memcpy(result, mem->data, size);
/* Done. */
return result;
}
errno = EINVAL;
return NULL;
}
static void mem_retirer(struct any_factory *any)
{
if (any) {
struct mem_factory *mem = (struct mem_factory *)any;
mem->produce = NULL;
mem->retire = NULL;
mem->size = 0;
free(mem);
}
}
/* The only exported function:
*/
struct any_factory *mem_factory(const void *src, const size_t len)
{
struct mem_factory *mem;
if (len && !src) {
errno = EINVAL;
return NULL;
}
mem = malloc(len + sizeof (struct mem_factory));
if (!mem) {
errno = ENOMEM;
return NULL;
}
mem->produce = mem_producer;
mem->retire = mem_retirer;
mem->size = len;
if (len > 0)
memcpy(mem->data, src, len);
return (struct any_factory *)mem;
}
Essentially, the struct any_factory type is actually polymorphic (not in the application, but within the library only). All its variants (struct mem_factory here) has the two initial function pointers in common.
Now, if we examine the code above, and consider the factory pattern, you should realize that the function pointers provide very little of value: you could just use the polymorphic type I showed earlier in this answer, and have the inline producer and consumer functions call subtype-specific internal functions based on the type of the factory. factory.h:
#ifndef FACTORY_H
#define FACTORY_H
#include <stdlib.h>
struct factory {
/* Common member across all factory types */
const int type;
/* Flexible array member to stop applications
from declaring static factories. */
const unsigned long data[];
};
/* Generic producer function */
void *produce(const struct factory *);
/* Generic factory discard function */
void retire(struct factory *);
/*
* Library functions that return factories.
*/
struct factory *mem_factory(const void *, const size_t);
#endif /* FACTORY_H */
and factory.c:
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "factory.h"
enum {
INVALID_FACTORY = 0,
/* List of known factory types */
MEM_FACTORY,
/* 1+(the highest known factory type) */
NUM_FACTORY_TYPES
};
struct mem_factory {
int type;
size_t size;
char data[];
};
/* The visibility of this union ensures the initial sequences
in the structures are compatible; see C11 6.5.2.3p6.
Essentially, this causes the casts between these structure
types, for accessing their initial common members, valid. */
union all_factories {
struct factory factory;
struct mem_factory mem_factory;
};
/* All factories thus far implemented
are a single structure dynamically
allocated, which makes retiring simple.
*/
void retire(struct factory *factory)
{
if (factory &&
factory->type > INVALID_FACTORY &&
factory->type < NUM_FACTORY_TYPES) {
/* Poison factory type, to make it easier
to detect use-after-free bugs. */
factory->type = INVALID_FACTORY;
free(factory);
}
}
char *mem_producer(struct mem_factory *mem)
{
/* As a courtesy for users, return the memory
padded to a length multiple of 16 chars
with zeroes. No real reason to do this. */
const size_t size = (mem->size | 7) + 9;
char *result;
result = malloc(size);
if (!result) {
errno = ENOMEM;
return NULL;
}
/* Clear padding. */
memset(result + size - 16, 0, 16);
/* Copy data, if any. */
if (mem->size)
memcpy(result, mem->data, mem->size);
return result;
}
/* Generic producer function.
Calls the proper individual producers.
*/
void *factory_producer(struct factory *factory)
{
if (!factory) {
errno = EINVAL;
return NULL;
}
switch (factory->type) {
case mem_factory:
return mem_producer((struct mem_factory *)factory);
default:
errno = EINVAL;
return NULL;
}
}
/* Library functions that return factories.
*/
struct factory *mem_factory(const void *ptr, const size_t len)
{
struct mem_factory *mem;
if (!ptr && len > 0) {
errno = EINVAL;
return NULL;
}
mem = malloc(len + sizeof (struct mem_factory));
if (!mem) {
errno = ENOMEM;
return NULL;
}
mem->type = MEM_FACTORY;
mem->size = len;
if (len > 0)
memcpy(mem->data, ptr, len);
return (struct factory *)mem;
}
If we look at standard C and POSIX C library implementations, we'll see that both of these approaches are used.
The standard I/O FILE structure often contains function pointers, and the fopen(), fread(), fwrite(), etc. functions are just wrappers around these. This is especially the case if the C library supports an interface similar to GNU fopencookie().
POSIX.1 socket, especially the struct sockaddr type, is the original prototype for the polymorphic structure shown first in this answer. Because their interface does not support anything similar to fopencookie() (that is, overriding the implementation of e.g. send(), recv(), read(), write(), close()), there is no need for the function pointers.
So, please do not ask which one is more suitable, as both are very commonly used, and it very much depends on minute details.. In general, I prefer the one that yields a simpler implementation providing all the necessary functionality.
I have personally found that it is not that useful to worry about future use cases without practical experience and feedback first. Rather than trying to create the end-all, best-ever framework that solves all future problems, the KISS principle and the Unix philosophy seem to yield much better results.
(Quoting your accepted answer to yourself)
Secondly a pointer to a parent struct can't receive a pointer to it's derived type (Embedded parent struct) so I can't do much there. I tried using void * but perhaps a solution might exists using memory address and then access some member of the struct without casting to specific types. I'll ask that in another question.
This is yet another pointer that one should learn the basics first. The thing you miss is called 'forward declaration':
struct chicken; // here we tell the compiler that 'struct chicken' is a thing
struct egg{
struct chicken *laidby; // while the compiler knows no details about 'struct chicken',
// its existence is enough to have pointers for it
};
struct chicken{ // and later it has to be declared properly
struct egg *myeggs;
};
What I'm missing is the ability to call the super method from the overridden run method in some way?
These are not methods and there is no override. In your code no OOP happens, C is a procedural programming language. While there are OOP extensions for C, you really should not go for them without knowing C basics.
First community told me that anonymous functions are not part of C, so the alternate suggestion is to use named functions and pointer to it.
Secondly a pointer to a parent struct can't receive a pointer to it's derived type (Embedded parent struct) so I can't do much there. I tried using void * but perhaps a solution might exists using memory address and then access some member of the struct without casting to specific types. I'll ask that in another question.
What I'm missing is the ability to call the super method from the overridden run method in some way?
src/super.h
struct Super {
void (*run)();
};
struct Super *newSuper();
src/super.c
static void run() {
printf("Running super struct\n");
}
struct Super *newSuper() {
struct Super *super = malloc(sizeof(struct Super));
super->run = run;
return super;
}
src/Runner.h
struct Runner {
void (*addFactoryMethod)(struct Super *(*ref)());
void (*execute)();
};
struct Runner *newRunner();
src/runner.c
struct Super *(*superFactory)();
void addFactoryMethod(struct Super *(*ref)()) {
superFactory = ref;
}
static void execute() {
struct Super *sup = superFactory(); // calling cached factory method
sup->run();
}
struct Runner *newRunner() {
struct Runner *runner = malloc(sizeof(struct Runner));
runner->addFactoryMethod = addFactoryMethod;
runner->execute = execute;
return runner;
}
test/runner_test.c
void anotherRunMethod() {
printf("polymorphism working\n");
// how can i've the ability to call the overridden super method in here?
}
struct Super *newAnotherSuper() {
struct Super *super = malloc(sizeof(struct Super));
super->run = anotherRunMethod;
return super;
}
void testSuper() {
struct Runner *runner = newRunner();
runner->addFactoryMethod(&newAnotherSuper);
runner->execute();
}
int main() {
testSuper();
return 0;
}
I am working on a database which has multiple structs. I have defined a function which loads data from a csv file and stores each line as a struct. I store them using a double pointer, so one pointer points to multiple pointers for each struct variable. The function does return the double pointer correctly, however I get a warning: return from incompatible pointer type.
My code is as follows:
struct part** loadParts(char* fileName, int m)
{
typedef struct part
{
int id;
int cost;
} Part;
FILE* fptr = fopen(fileName, "r");
//creat pointer to array of pointers to part structs
Part** parts;
parts = malloc((nParts) * sizeof(Part *));
//length of one line
char line[1000];
//while new items can be added
int i;
i=0;
while (fgets(line, sizeof(line), fptr)!= NULL)
{
parts[i] = malloc(sizeof(Part));
//get id
int id = atoi(strtok(line, ";"));
parts[i]->id = id;
// get cost
int id = atoi(strtok(line, ";"));
parts[i]->cost = cost;
i++;
}
fclose(fptr);
return parts;
}
Does anybody know why this warning occurs? Many thanks in advance!
You have in outline:
struct part** loadParts(char* fileName, int m)
{
typedef struct part
{
int id;
int cost;
} Part;
…
Part** parts;
…
parts = …
…
return parts;
}
There is no way that this will compile without warnings. The struct part used in the function signature is, by definition, wholly unrelated to the struct part defined inside the function. You are, therefore, returning a pointer to one type in a function that is expecting to return a pointer to a different type, even though those types may both be spelled struct part. There isn't even a way to cast your code out of trouble.
As indicated in the comments, the structure definition must come outside the function, before the function definition (and probably before any declaration — and typically in a header file that's used wherever the structure is used).
One way to fix the code, therefore, is:
typedef struct part
{
int id;
int cost;
} Part;
struct part **loadParts(char *fileName, int m)
{
…
Part **parts;
…
parts = …
…
return parts;
}
You could have the function return a Part ** in this scenario.
However, the function should now be defined as static unless you have a header to contain the structure definition. If you don't have a header, you can't (reliably) access the structure type in other source files. (It can be done by writing the code out twice, but writing code twice should be anathema — it becomes a maintenance liability before you've finished typing, or copy'n'pasting, the second copy.)
It is possible that you are dealing with an opaque type; the code outside this file doesn't need to know about the structure details. That's legitimate; it can even be (very) beneficial. You just need a different way of writing things, though:
Header:
typedef struct part Part;
extern struct part **loadParts(char *fileName, int m);
If you decide not to expose the name Part, you could use this header instead:
struct part;
extern struct part **loadParts(char *fileName, int m);
The first line says "there is a type struct part but the details will be supplied later, if you need them". The second declares the function returning a pointer to pointer to struct part value. The extern is optional; I use it — many people don't. In this code, the first line is optional. However, if you had extern int num_parts(struct part **list); as a function, you would need that to appear after the loadParts() declaration, or you would need the struct part; line to ensure that the type in the prototype is not new.
Source:
struct part
{
int id;
int cost;
};
struct part **loadParts(char *fileName, int m)
{
…
Part **parts;
…
parts = …
…
return parts;
}
You need to worry about header guards in the header to ensure idempotency. (In this example, there's no problem of self-containedness, but you should also ensure that your headers are self-contained — there are multiple questions on SO which will explain those terms if you search).
I have this code for example.
#include <stdlib.h>
#include <stdio.h>
#define array_size 3
typedef struct {
int array[array_size];
} TEST;
void printout(TEST *p, int element) {
printf("element: %i\n", p->array[element]);
}
int main(void) {
TEST *p;
p = malloc(sizeof(TEST));
p->array[0] = 5;
printout(p, 0);
return 0;
}
But I'd like to assign "array_size" based on user input.
If I try to do so, the compiler says "variably modified ‘array_size’ at file scope". So, am I right that the only way to do what I want is to move everything to main()..?
It works just fine, but keeping structs and functions declarations in file scope seems, you know, neat.
The simplest approach is to just allocate the memory dynamically:
typedef struct {
int *array;
size_t size;
} TEST;
int main() {
size_t elem_count = /* from user input */
TEST p;
p->array = malloc(elem_count * sizeof int);
if(!p->array)
return -1;
p->size = elem_count;
/* ... */
free(p->array);
}
You can indeed not define a variable length array at file scope, you can however define a pointer at file scope and malloc it, just define a global pointer int* p = NULL; (lose the whole TEST stuff) and p = malloc(sizeof(int) * input_size); simply access with p[x].
For completeness, you can also use the so called flexible array member defined in C99:
From ISO/IEC 9899:1999, Section 6.7.2.1, paragraph 16:
As a special case, the last element of a structure with more than one
named member may have an incomplete array type; this is called a
flexible array member.
typedef struct {
other_type other_data
int array[];
} TEST;
...
TEST *p = malloc(sizeof(TEST) + sizeof(int) * input_size);
Though note that this is limited to a single member, you could make an array of structs if you would otherwise have multiple arrays of different types but the same length.
This was originally intended mostly for data with headers such as ofter encountered in file and/or network I/O.
I'm designing a program in C that manipulates geometric figures and it would be very convenient if every type of figure could be manipulated by the same primitives.
How can I do this in C?
You generally do it with function pointers. In other words, simple structures that hold both the data and pointers to functions which manipulate that data. We were doing that sort of stuff years before Bjarne S came onto the scene.
So, for example, in a communications class, you would have an open, read, write and close call which would be maintained as four function pointers in the structure, alongside the data for an object, something like:
typedef struct {
int (*open)(void *self, char *fspec);
int (*close)(void *self);
int (*read)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
int (*write)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
// And the data for the object goes here.
} tCommsClass;
tCommsClass commRs232;
commRs232.open = &rs232Open;
: :
commRs232.write = &rs232Write;
tCommsClass commTcp;
commTcp.open = &tcpOpen;
: :
commTcp.write = &tcpWrite;
The initialisation of those function pointers would actually be in a "constructor" such as rs232Init(tCommClass*), which would be responsible for setting up the default state of that particular object to match a specific class.
When you 'inherit' from that class, you just change the pointers to point to your own functions. Everyone that called those functions would do it through the function pointers, giving you your polymorphism:
int stat = (commTcp.open)(commTcp, "bigiron.box.com:5000");
Sort of like a manually configured vtable, in C++ parlance.
You could even have virtual classes by setting the pointers to NULL -the behaviour would be slightly different to C++ inasmuch as you would probably get a core dump at run-time rather than an error at compile time.
Here's a piece of sample code that demonstrates it:
#include <stdio.h>
// The top-level class.
typedef struct _tCommClass {
int (*open)(struct _tCommClass *self, char *fspec);
} tCommClass;
// Function for the TCP class.
static int tcpOpen (tCommClass *tcp, char *fspec) {
printf ("Opening TCP: %s\n", fspec);
return 0;
}
static int tcpInit (tCommClass *tcp) {
tcp->open = &tcpOpen;
return 0;
}
// Function for the HTML class.
static int htmlOpen (tCommClass *html, char *fspec) {
printf ("Opening HTML: %s\n", fspec);
return 0;
}
static int htmlInit (tCommClass *html) {
html->open = &htmlOpen;
return 0;
}
// Test program.
int main (void) {
int status;
tCommClass commTcp, commHtml;
// Same base class but initialized to different sub-classes.
tcpInit (&commTcp);
htmlInit (&commHtml);
// Called in exactly the same manner.
status = (commTcp.open)(&commTcp, "bigiron.box.com:5000");
status = (commHtml.open)(&commHtml, "http://www.microsoft.com");
return 0;
}
This produces the output:
Opening TCP: bigiron.box.com:5000
Opening HTML: http://www.microsoft.com
so you can see that the different functions are being called, depending on the sub-class.
I'm astonished, does no one have mentioned glib, gtk and the GObject system.
So instead of baking yet-another-oo-layer-upon-C. Why not use something that has proofed to work?
Regards
Friedrich
People have done silly things with various types of structs and relying on predictable padding - for example you can define a struct with a particular subset of another struct and it'll usually work. See below (code stolen from Wikipedia):
struct ifoo_version_42 {
long x, y, z;
char *name;
long a, b, c;
};
struct ifoo_old_stub {
long x, y;
};
void operate_on_ifoo(struct ifoo_version_42 *);
struct ifoo_old_stub s;
...
operate_on_ifoo(&s);
In this example, the ifoo_old_stub could be considered a superclass. As you can probably figure out, this relies on the fact that the same compiler will pad the two structs equivalently, and trying to access the x and y of a version-42 will work even if you pass a stub. This ought to work in the reverse as well. But AFAIK it doesn't necessarily work across compilers, so be careful if you want to send a struct of this format over the network, or save it in a file, or call a library function with one.
There's a reason polymorphism in C++ is pretty complicated to implement... (vtables, etc)