This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: request for new a syntactic design for C/C++.


Ian Lance Taylor wrote:
"Vladimir 'Yu' Stepanov" <vys@renet.ru> 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;
		}
	}
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]