I think I got to the bottom of this, more or less. To answer some of my own questions - including one from a previous mail:
(value-Foo-1) works and (value-Foo-2) crashes. Is this expected?
Yes, a c-lambda that returns a (struct) *must* use ___alloc_rc for the pointer that gets returned via ___result_voidstar.
c-lambdas that return (pointer anything), including (pointer (struct)), can return arbitrary values in ___result_voidstar.
Also: is it OK to use malloc here or am I supposed to use ___alloc_rc or ___C_ASSIGN_NEW ?
No, malloc is not OK. That just worked by accident. ___C_ASSIGN_NEW and the other macros apparently can't be used in a c-declare block (because of CPP macro nesting?) so ___alloc_rc is the right answer.
Not sure what would happen if ___USE_RC_ALLOCATION_FOR_FOREIGN got un-defined. Could this happen or is rc-allocation-for-foreign here to stay?
Do I have to worry about providing code for releasing the memory allocated?
This I would still like to know, but I would suspect that I don't since the whole point of ___alloc_rc seems to be to create a block that can participate in Gambit memory management.
Finally, I am curious whether there is any difference internally between the handling of (struct "Foo") and (type "Foo"), or is this just naming for the sake of clarity?
I am also still interested in an answer to this.
All this is more or less guesswork so please let me know if the above is correct. If so, may I suggest updating the manual with this information.