0

I'm trying to avoid globals using twalk() in search.h

As you can see twalk callback a function but fails to include a void * param

/* Walk the nodes of a tree */
void
twalk(const void *vroot, void (*action)(const void *, VISIT, int))
{
    node *root = (node *)vroot;

    if (root != (node *)0 && action != (void (*)(const void *, VISIT, int))0)
        trecurse(root, action, 0);
}

void
action(const void *nodep, const VISIT which, const int depth)
{
    int *datap;

    switch (which) {
    case preorder:
        break;
    case postorder:
        datap = *(int **) nodep;
        printf("%6d\n", *datap);
        break;
    case endorder:
        break;
    case leaf:
        datap = *(int **) nodep;
        printf("%6d\n", *datap);
        break;
    }
}

What is the behaviour of re-declare the same struct (node_t in tsearch.c) with the same name in my own files?

/* twalk() fake */

struct node_t
{
    const void *key;
    struct node_t *left;
    struct node_t *right;
    unsigned int red:1;
};

static void tmycallback(const xdata *data, const void *misc)
{
    printf("%s %s\n", (const char *)misc, data->value);
}

static void tmywalk(const struct node_t *root, void (*callback)(const xdata *, const void *), const void *misc)
{
    if (root->left == NULL && root->right == NULL) {
        callback(*(xdata * const *)root, misc);
    } else {
        if (root->left != NULL) tmywalk(root->left, callback, misc);
        callback(*(xdata * const *)root, misc);
        if (root->right != NULL) tmywalk(root->right, callback, misc);
    }
}

/* END twalk() fake */

if (root) tmywalk(root, tmycallback, "Hello walker");
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • 1
    `datap = *(int **) nodep;` appears to be undefined behaviour, because `(int **) nodep` assumes that the representation of `int *` and `void *` (`((struct node_t *) nodep)->key`) are identical. This can cause bus errors. I suggest using: `datap = ((struct node_t *) nodep)->key;` instead. – autistic Feb 26 '13 at 10:48
  • @modifiablelvalue, thanks, but it's not my code http://unixhelp.ed.ac.uk/CGI/man-cgi?tsearch+3 – David Ranieri Feb 26 '13 at 10:53
  • @DavidRF, then drop it like a hot iron. It _will_ fail on 64 bit machines. – vonbrand Feb 26 '13 at 19:22
  • Thanks @vonbrand, its not included on my code, it was only a sample – David Ranieri Feb 26 '13 at 19:59

1 Answers1

0

What is the behaviour of re-declare the same struct (node_t in tsearch.c) with the same name in my own files?

Though there appears to be no mention of it in the C11 standard, many compilers will issue you a constraint violation diagnostic (error message) if you try to declare a struct twice in the same translation unit. It'd be a good idea to put the struct node_t declaration into it's own header file (perhaps tree_node.h) and use include guards to prevent duplicate declarations.

Community
  • 1
  • 1
autistic
  • 1
  • 3
  • 35
  • 80