1 + let val x = 1 in x * 2 end
That's both conceptually simpler and seems like one of the good solutions. struct node {
struct node *next;
int data;
};
struct node *copy_list(struct node *list_node) {
struct node *new_list, **indirect;
indirect = &new_list
while (list_node != NULL) {
// Pretend malloc can't fail
struct node *np = malloc(sizeof(*np));
np->data = list_node->data;
*indirect = np;
indirect = &np->next;
list_node = list_node->next;
}
*indirect = NULL;
return new_list;
}
The variable "new_list" is always initialized, no matter what, even though it's never explicitly on the left hand side of an assignment. If the while loop never ran, then indirect is pointing to the address of new_list after the loop, and the "*indirect = NULL;" statement sets it to NULL. If the loop did run, then "new_list" is set to the result of a call to malloc. In all cases, the variable is set.
Um, isn't it? Don't all Lisp variants have it? IIRC McCarthy's LISP just ran out of memory until the GC was written.