Ian Lance Taylor wrote:
"Vladimir 'Yu' Stepanov" <[EMAIL PROTECTED]> writes:

Current syntax C/C++:

  load_ptr = typeof(load_ptr)(((char *)init_ptr) - \
               offsetof(typeof(init_ptr), field);

The offered syntax:

  &load_ptr->field = init_ptr;

Interesting idea, but C/C++ programmers expect that an assignment sets
the entire expression on the left of the '='.  So I don't think this
is a good syntax.

   &load_ptr->field = init_ptr;

For given line only `load_ptr' variable will be changed. This changes based
on `init_ptr' variable and on the name of the field. Field name parameter is
static. May be it's not so dramatic ? Let me show you as example attached
file: "example1.c".

There is one another example. Many of interpretation languages have a general
header in the element structure (and not only languages). Type definition is
very frequently uses operation just for transit pointer to the object over
C-API:

struct head_of_object {
   int type;
   ...
};

struct one_type {
   struct head_of_object head;
   ...
};

Currently syntactic design definition of function and a few lines in
the body is look like:

struct head_of_object *
function(struct head_of_object *ob_head) {
   ...
   struct one_type *ob = (struct one_type *)ob_head;
   ...
   return &ob->ob_head;
   ...
}

This is some asymmetrically. Type definition in this case is not required.

With given purposes it will be become to look like:

struct head_of_object *
function(struct one_type &ob->head) {
   ...
   return &ob->ob_head;
   ...
}

For passed argument it is require pointer to a type of field `head'
(struct head_of_object *). In body of function pointer `ob' have
type "struct one_type". Magnitude this syntactic construction
is the same as in previous examples.

In fact you can already write what you want with a macro, one quite
similar to offsetof, so I don't think we need any new syntactic sugar
here.

It's really only syntactic changes. With this extension code become
more clear. Of course, it's not one way to do it. I just give one
clause.

And one more example:

   type_to_find *one_ptr;
   struct type2 {
       type1    field1;
       type2    field2;
       type_to_find field3;
   } *two_ptr = init_something;

   #if 1
       // case 1
one_ptr = &two_ptr->field3; // This is okay. Is it a really syntactic sugar ?
   #else
       // case 2
       one_ptr = typeof(one_ptr)(((char *)two_ptr) + \
                             sizeof(two_ptr->field1) + \
                             sizeof(two_ptr->field2)); // And this is okay.
                                                       // But nobody use it
                                                       // because it is
// heavily and unsafe.
   #endif

C++:
  struct some_struct &link = other;

This already means something in C++: it means to create a reference.

Yes. I just want to point for similar syntax.

typedef union __genlink {
        struct {
                union __genlink *qcl_prev;
                union __genlink *qcl_next;
        } qcl; /* Queue/Cycle/List */
        void    *point[2];
        union   __genlink *link[2];
} genlink;


struct timeout_and_refresh_list {
        int type;
        genlink node_timeout;
        genlink node_refresh;
        time_t tm_start;
        time_t tm_last;
        char *str;
};

genlink timeout_root;
genlink refresh_root;

void
qcl_init(genlink *root) {
        root->qcl.qcl_next = root;
        root->qcl.qcl_prev = root;
}

void
qcl_insert_before(genlink *root, genlink *p) {
        genlink *prev;

        p->qcl.qcl_next = root;
        p->qcl.qcl_prev = (prev = root->qcl.qcl_prev);
        root->qcl.qcl_prev = prev->qcl.qcl_next = p;
}

void
example_init() {
        qcl_init(&timeout_root);
        qcl_init(&refresh_root);
}

bool
example_add(struct timeout_and_refresh_list *list, char *str, time_t tm) {
        struct timeout_and_refresh_list *elem;
        genlink *p;
        for (p = &list->refresh_root;;) {
                /*
                 * Walk on the `refresh' list.
                 */
                if ((p = p->qcl.qcl_next) == &list->refresh_root) {
                        /*
                         * Element is not found. Make a new one.
                         */
                        if ((elem = malloc(sizeof(*elem))) == NULL)
                                goto failed;
                        elem->tm_start = elem->tm_last = tm;
                        elem->str = strdup(str);
                        qcl_insert_before(&refresh_root, elem);
                        qcl_insert_before(&timeout_root, elem);
                        break;
                }
#if 1 // Current syntax C/C++
                elem = (struct timeout_and_refresh_list *)(
                                ((char *)p) - \
                                offsetof(struct timeout_and_refresh_list,
                                        node_refresh)
                );
#else // The offered syntax
                // A type verification can be done.
                &elem->node_refresh = p;
#endif
                if (!strcmp(elem->str, str)) {
                        /*
                         * Found element `elem'.
                         */
                        qcl_remove(&elem->node_timeout);
                        qcl_insert_before(&timeout_root, &elem->node_timeout);
                        elem->tm_last = tm;
                        elem->type = TYPE_TIMEOUT_AND_REFRESH;
                        break;
                }
        }
}

Reply via email to