undefined reference to `memset'

Bruce Evans bde at zeta.org.au
Thu Mar 24 19:00:13 PST 2005


On Fri, 25 Mar 2005, Peter Jeremy wrote:

> On Thu, 2005-Mar-24 12:03:19 -0800, Vinod Kashyap wrote:
> [  char x[100] = { 0 };  ]
>> A statement like this (auto and not static)
>
> I'd point out that this is the first time that you've mentioned that
> the variable is auto.  Leaving out critical information will not
> encourage people to help you.

It was obviously auto, since memset() would not have been called for
a global variable.

>> is necessary if you
>> are dealing with re-entrancy.
>
> This isn't completely true.  The preferred approach is:
> 	char	*x;
> 	x = malloc(100, MEM_POOL_xxx, M_ZERO | M_WAITOK);
> (with a matching free() later).

This is also preferred to alloca() and C99's dynamic arrays.

BTW, the kernel has had some dubious examples of dynamic arrays in very
important code since long before C99 existed.  vm uses some dynamic
arrays, and this is only safe since the size of the arrays is bounded
and small.  But when the size of an array is bounded and small,
dynamic allocation is just a pessimization -- it is more efficient
to always allocate an array with the maximum size that might be needed.

>> How is it then, that an explicit call to memset (like in my example) works?
>
> The code
> 	auto char	x[100] = {0};
> is equivalent to
> 	auto char	x[100];
> 	memset(x, 0, sizeof(x));
> but memset only exists as a static inline function (defined in libkern.h).
> If an explicit call to memset works then the problem would appear to be
> that the compiler's implicit expansion is failing to detect the static
> inline definition, and generating an external reference which can't be
> satisfied.  This would seem to be a gcc bug.

No, it is a feature :-).  See my earlier reply.

>> 2. I should have mentioned that I don't see the problem if I am
>>   building only the kernel module.  It happens only when I am building
>>   the kernel integrating the module containing the example code.
>
> This is the opposite of what you implied previously.  There are some
> differences in how kernel modules are built so this
>
> How about posting a (short) compilable piece of C code that shows the
> problem.  I would expect that an "nm" of the resultant object would
> show "U memset" when the code was compiled for linking into the kernel
> and "<some_address> t memset" or not reference memset at all when
> compiled as a module.

I deleted the actual example.  Most likely it would fail at load time
do to using memset().  Another possibility is for the code that needs
memset to be unreachable in the module since it is inside an ifdef.

Bruce


More information about the freebsd-amd64 mailing list