struct data offsets

G

g3rc4n

i was playing around with the idea of getting some sort of virtual
function functionality out of c when playing about with pointers and i
was trying to do something like this

void say_hi();

struct foo{
unsigned offset;
int something;
double somethingelse;
void (*fun)();
};

struct bar{
unsigned function_offset;
void(*the_function)();

};

void init(struct foo* arg){
arg->offset = foo::fun;
arg->fun = say_hi;
}

void init(struct bar* arg){
arg->function_offset = bar::the_function;
arg->the_function = say_hi;

}

void fun(void* arg){
arg += (void*)(unsigned*)arg; // i know this doesn't work
((void(*)())arg)();

}

int main(){
struct foo f;
init(&f);
fun(&f);
struct bar b;
init(&b);
fun(&b);
return 0;

}

so can you just read the offset of a structs data then mainpulate the
void* and do something with it?
 
F

Fred

i was playing around with the idea of getting some sort of virtual
function functionality out of c when playing about with pointers and i
was trying to do something like this

void say_hi();

struct foo{
  unsigned offset;
  int something;
  double somethingelse;
  void (*fun)();

};

struct bar{
  unsigned function_offset;
  void(*the_function)();

};

void init(struct foo* arg){
  arg->offset = foo::fun;

Syntax error - or this is some language other than C
 
J

Joachim Schmitz

Fred said:
Syntax error - or this is some language other than C

Indeed, virtual functions and the foo::fun syntax is C++

To the OP: try comp.lang.c++ instead.

Bye, Jojo
 
G

g3rc4n

Indeed, virtual functions and the foo::fun syntax is C++

To the OP: try comp.lang.c++ instead.

Bye, Jojo

no, this is a question about how structs work, the c++ code is purly
to get across what i'm trying to achive, i want to know if you want
work out the offsets of data members, can you?
 
K

Keith Thompson

no, this is a question about how structs work, the c++ code is purly
to get across what i'm trying to achive, i want to know if you want
work out the offsets of data members, can you?

Do you know about the offsetof macro (which I mentioned when you
posted your question in comp.std.c)?
 
S

Stephen Sprunk

i was playing around with the idea of getting some sort of virtual
function functionality out of c when playing about with pointers and i
was trying to do something like this

void say_hi();

struct foo{
unsigned offset;
int something;
double somethingelse;
void (*fun)();
};

struct bar{
unsigned function_offset;
void(*the_function)();

};

void init(struct foo* arg){
arg->offset = foo::fun;

foo::fun is a syntax error in C.
arg->fun = say_hi;
}

void init(struct bar* arg){

You cannot have two different functions with the same name in C.
arg->function_offset = bar::the_function;

bar::the_function is a syntax error in C.
arg->the_function = say_hi;

}
>
void fun(void* arg){
arg += (void*)(unsigned*)arg; // i know this doesn't work

If you know it doesn't work, at least try to explain what you're trying
to do, since incrementing one void pointer by another void pointer is
completely nonsensical.
((void(*)())arg)();

That makes my brain hurt. Function pointers are a very, very good
reason to use typedefs.
}

int main(){
struct foo f;
init(&f);
fun(&f);
struct bar b;
init(&b);
fun(&b);
return 0;

}

so can you just read the offset of a structs data then mainpulate the
void* and do something with it?

What void*? The only (void *)s in your code is the argument to fun().



Here's what I think you're trying to do:

typedef void (*fptr)();

void foo_say_hi();
void bar_say_hi();

struct foo {
fptr fun;
};

void foo_init(struct foo *arg){
arg->fun = foo_say_hi; /* set base method in vtable */
}

struct foo {
fptr fun; /* copy all elements of parent struct at beginning */
int something; /* new elements in child struct */
double somethingelse;
};

void bar_init(struct bar *arg){
foo_init(arg); /* always chain to parent's constructor */
arg->fun = bar_say_hi; /* override base method in vtable */
}

int main(){
struct foo f;
foo_init(&f); /* call constructor */
f.fun(); /* calls foo_say_hi() */

struct bar b;
bar_init(&b); /* call constructor */
b.fun(); /* calls bar_say_hi() */

return 0;
}
 
G

g3rc4n

foo::fun is a syntax error in C.



You cannot have two different functions with the same name in C.


bar::the_function is a syntax error in C.




If you know it doesn't work, at least try to explain what you're trying
to do, since incrementing one void pointer by another void pointer is
completely nonsensical.


That makes my brain hurt.  Function pointers are a very, very good
reason to use typedefs.



What void*?  The only (void *)s in your code is the argument to fun().

Here's what I think you're trying to do:

typedef void (*fptr)();

void foo_say_hi();
void bar_say_hi();

struct foo {
   fptr fun;

};

void foo_init(struct foo *arg){
   arg->fun = foo_say_hi;  /* set base method in vtable */

}

struct foo {
   fptr fun; /* copy all elements of parent struct at beginning */
   int something; /* new elements in child struct */
   double somethingelse;

};

void bar_init(struct bar *arg){
   foo_init(arg); /* always chain to parent's constructor */
   arg->fun = bar_say_hi; /* override base method in vtable */

}

int main(){
   struct foo f;
   foo_init(&f); /* call constructor */
   f.fun(); /* calls foo_say_hi() */

   struct bar b;
   bar_init(&b); /* call constructor */
   b.fun(); /* calls bar_say_hi() */

   return 0;

}

k to be honest i've only coded c++ before but i thought as this was
more a low level "c struct" question, ignore this thread untill i come
up with an appropriate example, i'll admit that i didn't explain what
i wanted to do at all thus wasted your time
 
G

g3rc4n

i was playing around with the idea of getting some sort of virtual
function functionality out of c when playing about with pointers and i
was trying to do something like this

void say_hi();

struct foo{
  unsigned offset;
  int something;
  double somethingelse;
  void (*fun)();

};

struct bar{
  unsigned function_offset;
  void(*the_function)();

};

void init(struct foo* arg){
  arg->offset = foo::fun;
  arg->fun = say_hi;

}

void init(struct bar* arg){
  arg->function_offset = bar::the_function;
  arg->the_function = say_hi;

}

void fun(void* arg){
  arg += (void*)(unsigned*)arg; // i know this doesn't work
  ((void(*)())arg)();

}

int main(){
  struct foo f;
  init(&f);
  fun(&f);
  struct bar b;
  init(&b);
  fun(&b);
  return 0;

}

so can you just read the offset of a structs data then mainpulate the
void* and do something with it?

this is what i was trying to do

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

void say_hi(){
printf("hi\n");
}
void say_bye(){
printf("bye\n");
}

typedef struct{
size_t offset;
void* ptr;
}foo_a;

void init_foo_a(foo_a* arg){
arg->offset = __builtin_offsetof(foo_a,ptr);
arg->ptr = (void*)say_hi;
}

typedef struct{
size_t offset_;
int something;
double somethingelse;
void* fun_ptr;
char lastsomething;
}foo_b;

void init_foo_b(foo_b* arg){
arg->offset_ = __builtin_offsetof(foo_b,fun_ptr);
arg->fun_ptr = (void*)say_bye;
}

void call_function(void* ptr){
size_t offset = *((size_t*)ptr);
char* temp = (char*)ptr;
temp = temp + offset;
ptr = (void*)temp;
void(**fun)() = (void(**)())ptr;
(**fun)();
}

void g(){
foo_a f;
init_foo_a(&f);
call_function((void*)&f);

foo_b ff;
init_foo_b(&ff);
call_function((void*)&ff);

}

int main(){
g();
exit(0);
}


to be able to have structs where the first data memeber was a size_t
to the offet of the pointer to a function, where structs could be
layed out differently

seemed like a good idea at first, seems pointless now as it is, but i
want to see if i could implement a virtual table or something

thanks for your help, it was the offsetof that i wanted, although the
macro only gave me errors so i had to use the gcc function
 
K

Keith Thompson

thanks for your help, it was the offsetof that i wanted, although the
macro only gave me errors so i had to use the gcc function

If the macro is giving you errors, you're almost certainly using it
wrong. Show us some sample code that fails, along with the error
messages you received. (Copy-and-paste both *exactly*.)

Incidentally, it's rarely necessary to quote the entire parent article
when you post a followup. Trim anything that's not necessary for
context, as I've done here.
 
G

g3rc4n

Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>

right yeah sorry after i read your post i looked at to what header it
was in and it was stddef.h, just the compile error confused me, i
thought it would of said something like "offsetof not defined"

thanks for your help once again
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top