This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Divergence from BSD sources, e.g. __GNUC_PREREQ()
- From: Sebastian Huber <sebastian dot huber at embedded-brains dot de>
- To: newlib at sourceware dot org
- Date: Thu, 04 Apr 2013 09:59:13 +0200
- Subject: Divergence from BSD sources, e.g. __GNUC_PREREQ()
Hello,
I have some questions about the divergence from BSD sources. The background is
that <sys/queue.h> is broken in Newlib since __offsetof() is undefined. I
wanted to update the file in Newlib with the latest version from FreeBSD, but
now some problems arise.
What is the purpose of <sys/cdefs.h> in Newlib? This file seems to be derived
from BSD sources, but current BSD versions look quite different. For example
last year the new macro __GNUC_PREREQ() was introduced in
"libc/include/sys/features.h":
/* Macro to test version of GCC. Returns 0 for non-GCC or too old GCC. */
#ifndef __GNUC_PREREQ
# if defined __GNUC__ && defined __GNUC_MINOR__
# define __GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
# else
# define __GNUC_PREREQ(maj, min) 0
# endif
#endif /* __GNUC_PREREQ */
In FreeBSD we have a similar macro in <sys/cdefs.h>:
http://svnweb.freebsd.org/base/head/sys/sys/cdefs.h?revision=241374
/*
* Macro to test if we're using a specific version of gcc or later.
*/
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
#define __GNUC_PREREQ__(ma, mi) \
(__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi))
#else
#define __GNUC_PREREQ__(ma, mi) 0
#endif
Why don't we follow the BSD development more to simplify code re-use?
The latest version of FreeBSD <sys/queue.h> uses __containerof():
http://svnweb.freebsd.org/base/head/sys/sys/queue.h?revision=246387
It is defined in <sys/cdefs.h>:
/*
* Given the pointer x to the member m of the struct s, return
* a pointer to the containing structure. When using GCC, we first
* assign pointer x to a local variable, to check that its type is
* compatible with member m.
*/
#if __GNUC_PREREQ__(3, 1)
#define __containerof(x, s, m) ({ \
const volatile __typeof(((s *)0)->m) *__x = (x); \
__DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m));\
})
#else
#define __containerof(x, s, m) \
__DEQUALIFY(s *, (const volatile char *)(x) - __offsetof(s, m))
#endif
Any objections to:
1. Remove __GNUC_PREREQ in <sys/features.h>.
2. Add __GNUC_PREREQ__ in <sys/cdefs.h> like in FreeBSD.
3. Add __containerof() like in FreeBSD.
4. Update <sys/queue.h> with latest FreeBSD version.
--
Sebastian Huber, embedded brains GmbH
Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail : sebastian.huber@embedded-brains.de
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.