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;
}
}
}