C

Programming, for all ages and all languages.
Post Reply
Balroj

C

Post by Balroj »

Hi,

i've got some trouble with 2 c code:

Code: Select all

typedef void (*syscall_func)(void);
i can't understand what it's been defined with that. what's the use of de last (void) ?

Code: Select all

static union header {
struct {
    union header *link;
    unsigned size;
} s;
    union align {
      double d; unsigned u; void (*f)(void);
} x;
} freelist = { &freelist, 0 }, *freep = &freelist;
This one is taken from the the pdf in osdever.net. Can anyone explainme that?


Thanks far all.
AR

Re:C

Post by AR »

Code: Select all

typedef void (*syscall_func)(void);
This is a function pointer, the void represents the arguments the function takes (ie. none). I assume you're referring to the function pointer again in the second one as well.

Here's a demonstration of a function pointer:

Code: Select all

#include <stdio.h>

int SayHello(int A, int B)
{
     printf("Hello, A=%i B=%i\n", A, B);
     return 67;
}

int SayHello2(int X, int Y)
{
     printf("Hello from SayHello2, X=%i Y=%i\n", X, Y);
     return 89;
}

//This declares a type called "HelloFunc" which represents a pointer to a function the takes 2 ints and returns an int
typedef int (*HelloFunc)(int,int);

int main()
{
     HelloFunc h = SayHello;   //Set the function pointer
     int r = h(6, 9);    //Call it
     printf("HelloFunc Function Pointer returned %i", r);

     h = SayHello2;    //Change the pointer
     r = h(90, 198);   //Call it again
     printf("HelloFunc Function Pointer returned %i", r);
     return 0;
}
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:C

Post by Solar »

Code: Select all

static union header {
Declare a [tt]static union[/tt] (i.e., a union without external linkage) called "header".

A union is a datatype that can hold either of the declared datatypes. That means, while...

Code: Select all

struct foo
{
   int x;
   float f;
};
...can hold an [tt]int[/tt] and a [tt]float[/tt], ...

Code: Select all

union foo
{
   int x;
   float f;
};
...can hold an [tt]int[/tt] or a [tt]float[/tt], depending on whether you last wrote to [tt]foo.x[/tt] or [tt]foo.f[/tt].

Code: Select all

struct {
    union header *link;
    unsigned size;
} s;
"s" is the one possible content of an "header union", with "s" consisting of a "pointer to header union" named "link" (i.e., pointer to next "header" most likely), and an unsigned integer named "size".

Code: Select all

union align {
      double d; unsigned u; void (*f)(void);
} x;
"x" is the other possible content of an "header union", being a union itself holding either:
  • a double,
  • an unsigned int,
  • a pointer to a function accepting no arguments and not returning a value.

Code: Select all

} freelist = { &freelist, 0 }, *freep = &freelist;
One object of type "header union" is declared, named "freelist", with [tt]freelist.s.link[/tt] initialized with a pointer to "freelist" itself, and [tt]freelist.s.size[/tt] initialized to zero.

Afterwards, a "pointer to header union" is declared, named "freep", and initialized to point to the [tt]freelist[/tt] object we just initialized.

And while I'm at it, code like this - with lots and lots of unions, implicit initialization and comma operators, but lacking liberal comments - does ring every alarm bell in my head, for it seems someone really enjoyed his l33t sk1llz at writing l33t code. 8)
Every good solution is obvious once you've found it.
Balroj

Re:C

Post by Balroj »

thanks Solar and AR,

what's the really use of union? I mean, what's the diference/use betwen declare an union:

Code: Select all

union d
{
    int a;
    char b;
}
and declare 2 different variables:

Code: Select all

int a
char b;
Thanks for all
Curufir

Re:C

Post by Curufir »

The union will take up less space. It only has to allocate for the integer, because that is the longest variable. With the two separate variables memory must be allocated for both.

Solar is right IMHO, unions are hackish and will get you in all sorts of trouble very quickly.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:C

Post by Solar »

Curufir wrote: The union will take up less space. It only has to allocate for the integer, because that is the longest variable. With the two separate variables memory must be allocated for both.
You can also refer to two different data structures with one and the same pointer type, which can make sense in low-level list handling code. But it's a dangerous game - all too easily you've written one value and read the other, which is a bi*ch to debug.

It's a hardcore C coder's idea of mimicking C++ polymorphism, and even C++ coders customarily get it wrong the first time around.
Every good solution is obvious once you've found it.
Just another guest

Re:C

Post by Just another guest »

A use I can think of for a union is to do something like this:

Code: Select all

union reg
{
  struct w
  {
    short low;
    short high;
  }
  long full;
}
or however it would be written properly (there's probably some bad syntax there, but I'm too lazy to make it perfect). Also, if you wanted it to be portable across CPUs with different endiness, you'd want some defines or something to order the highs and lows correctly.
Schol-R-LEA

Re:C

Post by Schol-R-LEA »

There are several kinds of data structures - especially in binary file formats - where the effective type of one variable depends on the value of another variable in the same data structure. This is what is called a 'discriminated union' (or a 'variant record' in Pascal and it's descendants), and while they are generally better avoided (especially since, as Solar correctly points out, polymorphism will usually work better), there are times when it is useful, mostly when dealing with the same sorts of old and/or proprietary data formats which rely heavily on bit fields.

As Just Another Guest points out, it can also be used for manipulating partial values of larger variables, or conversely, for 'packing' small values into one larger one.

They also open a hole in the type system which can be exploited for all kinds of weird bit-fiddling purposes, but to be honest you really don't want to go there unless you absolutely have to.
Post Reply