Re: glib: alloca brain damages



Elliot Lee wrote:
> 
> On Mon, 4 Jan 1999, Tim Janik wrote:
> 
> > On Mon, 4 Jan 1999, Elliot Lee wrote:
> > 
> > > 1.
> > > 
> > > #  define g_new0_a(type, count)	  \
> > >       ((type *) memset (alloca ((unsigned) sizeof (type) * (count)), 0, \
> > >       			((unsigned) sizeof (type) * (count))))
> > > 
> > > Very bad - this is allocating a place on the stack while the compiler is
> > > trying to set up the stack for the function call. It should be something
> > > like
> 
> > > #  define g_new0_a(type, count)	\
> > > 	G_STMT_STRT { \
> > > 		char *newblock;
> > > 		newblock = alloca(sizeof(type) * count);
> > > 		memset(newblock, 0, sizeof(type) * count);
> > > 	} G_STMT_END
> > > 
> > > 
> > > The problem is that G_STMT_STRT casts the block to (void), and ANSI C does
> > > not permit ({expr;}), so there's really no way to do it portably.
> > > 
> > > 2. There's the whole problem of doing all these macros at all. On some
> > > arches/OS's, alloca() won't work inside conditionals, or inside {} blocks.
> > 
> > hm, sopwith, can you eventually provide concrete reports about such
> > behaviour? we shouldn't provide alloca using macros at all if that's affecting
> > any system that glib currently runs on.
> 
> OK, #2 was a misunderstanding on my part, but #1 most definitely is a
> problem. RTH says any machine that does push/pop (m68k, x86) will have
> problems with that.

Can you give me a simple test case where it fails on these platforms?
It seems to work fine on an Alpha and a 486 with 'make check', and
the test program enclosed below.


> So, either the signature of g_new0_a needs to change, or we need to use
> the ({ ... }) construct (which is a gcc extension).

g_new0_a should be globally available, so gcc statement expressions are
out.  Unless something better comes along, it may be necessary to make
it a void expression as with g_strdup_a and friends.

#define g_new_a(newptr,type,count)
#define g_new0_a(newptr,type,count)

	Jeff




#include <string.h>
#include <glib.h>

#define TEST_STR "papa wons haz gud fud"
#define TEST_STR_2 "%d soup is gud fud %d"
#define NUM_RECURSIONS 15

void do_recurse (int recno)
{
  char *s, s1[80], s2[80];

  if (recno < 1)
    return;

  g_assert(sprintf(s1, TEST_STR_2, recno, recno * 42) > 0);

  g_strconcat3_a(s, TEST_STR, TEST_STR, NULL);
  g_assert(s != NULL);

  do_recurse(recno - 1);

  g_assert(strcmp(s, TEST_STR TEST_STR) == 0);

  g_assert(sprintf(s2, TEST_STR_2, recno, recno * 42) > 0);
  g_assert(strcmp(s1, s2) == 0);
}



int main()
{
  do_recurse(NUM_RECURSIONS);
  return 0;
}




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