chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] c-string return question


From: Jörg F . Wittenberger
Subject: Re: [Chicken-users] c-string return question
Date: 13 Oct 2011 19:09:32 +0200

On Oct 13 2011, John Cowan wrote:

Jörg F. Wittenberger scripsit:

(define integer->utf8string
 (foreign-lambda*
  c-string ((unsigned-integer ch))
  "static C_uchar off[6]={0xFC,0xF8,0xF0,0xE0,0xC0,0x00};
 int size=5; C_uchar buf[7];
 buf[6]='\\0';
 if (ch < 0x80) {
   buf[5]=ch;
 } else {
   buf[size--]=(ch&0x3F)|0x80; ch=ch>>6;
   while (ch) { buf[size--]=(ch&0x3F)|0x80; ch=ch>>6; }
   /* Write the size information into the first byte */
   ++size;
   buf[size]=off[size]|buf[size];
 }
 return(buf+size);
"))

This code is not good C, because it returns a pointer into a stack
frame which has already been exited.  It may just so happen that
there is still a correct value there, but there are no guarantees.
I'd guess that the corruption happens when there is a minor GC.
See http://c-faq.com/~scs/cclass/int/sx5.html .

Wait!

The chicken manual does not mention this restriction.  For a reason.

When you read the expanded C code as Chicken produces,
you will find, that it does through some magic to make sure
this restriction shall not apply.

(Watch out for C_cblock and C_cblockend #defines in chicken.h
, which depend on the C compiler in use.)

It does a local #define return(x) to insert a block wherein it
saves the to-be-returned string *before* the actual return statement
is seen by the C compiler.

1.) static C_uchar buf[7];
   ^^^^^^
   does the trick.

That's absolutely the Right Thing.  You are now returning a pointer to
the static data region, which will always be available.

Not exactly.  While your explanation of my reasoning how to circumvent
the none-working situation is correct, this means that
the trick as deployed in the Chicken source does not work under certain
C compilers.


Best Regards

/Jörg







reply via email to

[Prev in Thread] Current Thread [Next in Thread]