Coherent4.2.10/include/common/_ccompat.h
/* (-lgl
* Coherent 386 release 4.2
* Copyright (c) 1982, 1993 by Mark Williams Company.
* All rights reserved. May not be copied without permission.
* For copying permission and licensing info, write licensing@mwc.com
-lgl) */
#ifndef __COMMON__CCOMPAT_H__
#define __COMMON__CCOMPAT_H__
/*
* Define some handy things that allow us to work with K&R, ANSI and C++
* compilers in a way that is at least less painful than not working. This
* file does mandate an ANSI C pre-processing environment.
*
* While ANSI allows us to not define function prototypes, C++ mandates that
* they exist, and it's a *really* good idea to use them whereever possible.
*
* This file also deals with some compiler-specific features that are either
* in the C or C++ language standards but not always available, and some
* language extensions that are very widely available, if only because they
* are part of the C++ standard and have been incorporated into C compilers.
*
* This file specifically excludes specifics about target machines and
* compiler interactions. Such definitions belong in another file.
*/
#include <common/feature.h>
#include <common/__offset.h>
/*
* There is some complexity on the way __STDC__ is used in practice: the ANSI
* committee merely says that if __STDC__ is defined and value 1, then the
* implementation is ISO-conforming.
*
* Unfortunately, much existing code uses #ifdef as the only test, which
* means that some non-conforming compilers which defined __STDC__ as zero
* caused problems (the Coherent 3.x compiler is one such; the 4.x compiler
* uses the alternate convention). The #if test is preferable in programs,
* since in preprocessor tests undefined symbols assume value 0, but still
* many programs use the alternate form.
*
* For compilers with an intermediate status, eg. with an ISO preprocessor,
* or support for "const" but not prototypes, or prototypes but not "const"
* we perform individual featurectomies below.
*
* A general rule for future extensions: use double-underscores before and
* after for non-parameterized macros, double-underscores before for macros
* that take parameters. If this file's definitions are to be used by user-
* level code, create a header that exports the definitions into the user
* namespace.
*
* Jun '93 - split profile in two sections in anticipation of future growth.
* We can't assume more than 16-bit arithmetic because of some extremely
* losing preprocessors out there.
*/
/* __STD_PROFILE__ bits */
#define __STRINGIZE_M__ 0x0001 /* supports ISO C "stringize" */
#define __PASTE_M__ 0x0002 /* support ISO C token-pasting */
#define __PROTODECL_M__ 0x0004 /* supports prototype declarations */
#define __PROTODEFN_M__ 0x0008 /* supports prototype definitions */
#define __CONST_M__ 0x0010 /* supports "const" construct */
#define __VOLATILE_M__ 0x0020 /* supports "volatile" construct */
#define __VOIDSTAR_M__ 0x0040 /* supports "void *" type */
#define __STD_PROFILE_MASK__ 0x007F
/* __MISC_PROFILE__ bits */
#define __NOTUSED_M__ 0x0001 /* allows "not used" warning suppression */
#define __REGISTER_M__ 0x0002 /* requires "register" declaration */
#define __LINKID_M__ 0x0004 /* requires linkage specifier (e.g. C++) */
#define __INLINE_M__ 0x0008 /* allows inline functions */
#define __INLINEL_M__ 0x0010 /* allows inline functions with loops */
#define __DOTDOTDOT_M__ 0x0020 /* requires (...) rather than () */
#define __NOMERGESTR_M__ 0x0040 /* cannot merge identical strings */
#define __ANONUNION_M__ 0x0080 /* allows anonymous unions (e.g. C++) */
#define __MISC_PROFILE_MASK__ 0x00FF
/*
* The Standard C language features in one definition for simplicity. This may
* not be all the bits in __STD_PROFILE_MASK__ once C++ standards start
* hitting the streets. Normative addenda to ISO C will complicate this, too.
*/
#define __STDC_M__ (__STD_PROFILE_MASK__)
/*
* Below, we attempt to determine a configuration suitable for the translator
* that is working on the current program. Each group of macros attempts to
* set a preprocessor macro __PROFILE__ with a bit-mask of the features
* supported by the current translator.
*
* This approach has been taken since it considerably simplifies both the
* task of adding new features to test for and adding new translators. Many
* other programs intermingle the tasks of determining the translator and
* defining the responses to that determination; in general, such programs
* fail to be maintainable when the matrix of features and translators grows
* larger than about 3x3.
*
* Jun '93 - With the split into two parts, we still let people use the single
* __PROFILE__ definition if their translator's preprocessor can deal with
* 32-bit arithmetic.
*/
#if defined (__PROFILE__) /* user-overridden */
# if (1 << 31) == 0
# error Your preprocessor cannot handle 32-bit arithmetic!
# endif
# if __PROFILE__ & ~ (__STD_PROFILE_MASK__ | (__MISC_PROFILE_MASK << 16))
# error __PROFILE__ contains unknown flag bits.
# endif
# define __STD_PROFILE__ (__PROFILE__ & __STD_PROFILE_MASK__)
# define __MISC_PROFILE__ ((__PROFILE__ >> 16) & __MISC_PROFILE_MASK__)
#elif defined (__STD_PROFILE__) || defined (__MISC_PROFILE__)
# ifndef __STD_PROFILE__
# error If you defined __MISC_PROFILE__, you must also define __STD_PROFILE__
# elif __STD_PROFILE__ & ~ __STD_PROFILE_MASK__
# error Unknown bits set in __STD_PROFILE__
# endif
# ifndef __MISC_PROFILE__
# error If you defined __STD_PROFILE__, you must also define __MISC_PROFILE__
# elif __MISC_PROFILE__ & ~ __MISC_PROFILE_MASK__
# error Unknown bits set in __MISC_PROFILE__
# endif
#elif defined (__cplusplus) /* C++ */
# ifdef __GNUC__
# define __STD_PROFILE__ __STDC_M__
# define __MISC_PROFILE__ (__NOTUSED_M__ | __LINKID_M__ | \
__INLINE_M__ | __INLINEL_M__ | \
__DOTDOTDOT_M__ | __ANONUNION_M__)
# else
# define __STD_PROFILE__ __STDC_M__
# define __MISC_PROFILE__ (__NOTUSED_M__ | __LINKID_M__ | \
__INLINE_M__ | __DOTDOTDOT_M__ | \
__ANONUNION_M__)
# endif
#elif __BORLANDC__ /* Borland C */
# if __BORLANDC__ >= 0x410
# define __STD_PROFILE__ __STDC_M__
# define __MISC_PROFILE__ 0 /* features restricted to C++ */
# else
# define __STD_PROFILE__ __STDC_M__
# define __MISC_PROFILE__ (__NOTUSED_M__ | __INLINE_M__)
# endif
#elif defined (__GNUC__) /* GCC w/o C++ */
# define __MISC_PROFILE__ (__INLINE_M__ | __INLINEL_M__ | \
__ANONUNION_M__)
# if __STDC__ + 0 /* regular */
# define __STD_PROFILE__ __STDC_M__
# else /* -traditional */
# define __STD_PROFILE__ (__STDC_M__ & ~ __PASTE_M__ & \
~ __STRINGIZE_M__)
# define __CONST__ __NON_ISO (const)
# define __VOLATILE__ __NON_ISO (volatile)
# endif
#elif __STDC__ + 0 /* minimal ANSI C */
# define __STD_PROFILE__ __STDC_M__
# define __MISC_PROFILE__ 0
#elif __COHERENT__ /* MWC Coherent */
# define __STD_PROFILE__ (__STRINGIZE_M__ | __PASTE_M__)
# define __MISC_PROFILE__ (__REGISTER_M__ | __NOMERGESTR_M__)
#else /* VANILLA */
# define __STD_PROFILE__ 0
# define __MISC_PROFILE__ __REGISTER_M__
#endif
/*
* In the following sections we determine the responses to take on the basis
* of whether or not each feature/misfeature is supported by the current
* translator.
*
* In cases where the feature requires considerable change to source code,
* such as prototyping and inline functions, we define both an existence
* feature-test and a value macro.
*
* For the case of inline functions, this is because the function should not
* appear at all in the souce code unless unlining is supported (and because
* often a macro may suffice in place, although with less safety).
*
* In addition, the tests below always check to see whether a particular
* symbol is defined already, allowing almost any feature to be turned on or
* off at will from the command-line. This is useful when testing the
* characteristics of a new translator, and may often be useful to suppress
* certain features to aid in debugging.
*/
/*
* Some old Reiser preprocessors looked for macro-expansions unside quoted
* strings; this was useful, but dangerous, so ISO C defined a new operator
* for doing just this job. A tip of the hat to P.J. Plauger for the form of
* these macros.
*/
#ifndef __STRING
# if __STD_PROFILE__ & __STRINGIZE_M__
# define __STRING(x) #x
# define __STRINGVAL(x) __STRING(x)
# define _HAVE_STRINGIZE 1
# else
# define __STRING(x) "x"
# define __STRINGVAL(x) __STRING(x)
# endif
#endif
/*
* As above, this is a feature supported in old systems by ill-advised hacks,
* so ISO C has a special operator just for the job. We define __CONCAT3 ()
* and __CONCAT4 () as primitives just for fun; it's handy, and nested calls
* to __CONCAT () are just too messy to be practical. Furthermore, many of the
* users of token-pasting need to be very careful about avoiding extra
* rescanning when building a composite token, since some of the intermediate
* steps may match other macros; sometimes this is useful, sometimes not.
*/
#ifndef __CONCAT
# if __STD_PROFILE__ & __PASTE_M__
# define __CONCAT(x,y) x##y
# define __CONCAT3(x,y,z) x##y##z
# define __CONCAT4(a,b,c,d) a##b##c##d
# else
# define __CONCAT(x,y) x/**/y
# define __CONCAT3(x,y,z) x/**/y/**/z
# define __CONCAT4(a,b,c,d) a/**/b/**/c/**/d
# endif
#endif
/*
* __USE_PROTO__ is a general test which can be performed in .c files to see
* whether to use a prototype form or a K&R form, since the two are so
* different. This has the advantage that some tools which are hard-wired for
* K&R source code can get confused by macros in the function header, so
* keeping a real K&R header around can help.
*
* __PROTO () is a macro that can be used in header files, since all that
* differs between K&R and ANSI external declarations is whether the types
* are present.
*
* The difference between the two is important, especially when "lint"-like
* tools are used. In order to check for consistency between the prototype
* and K&R-style definitions, it may be necessary to enable prototypes in
* the header files while suppressing them in the C files.
*/
#ifndef __PROTO
# if __STD_PROFILE__ & __PROTODECL_M__
# define __PROTO(p) p
# else /* prototypes are not supported */
# define __PROTO(p) ()
# endif
# if __STD_PROFILE__ & __PROTODEFN_M__
# define __USE_PROTO__ 1
# endif
#endif /* ! defined (__PROTO) */
/*
* There are several existing compilers still in use which either do not
* support the notion of a "const" language element or implement the feature
* incorrectly with respect to the C standard.
*
* For these compilers, we allow the "const" specifier in prototypes, local
* variables and structure declarations to be suppressed. Note that "const"
* will never appear in a K&R function header.
*/
#ifndef __CONST__
# if __STD_PROFILE__ & __CONST_M__
# define __CONST__ const
# else /* const is not supported */
# define __CONST__
# endif
#endif /* ! defined (__CONST__) */
/*
* For symmetry with the "const" definition, we provide a wrapper for the
* "volatile" feature. Note that for some reason "volatile" is available in
* some compilers that do not implement "const", probably because the feature
* was defined in simpler terms.
*
* For these compilers, we allow the "volatile" specifier in prototypes,
* local variables, and structure declarations to be suppressed.
*/
#ifndef __VOLATILE__
# if __STD_PROFILE__ & __VOLATILE_M__
# define __VOLATILE__ volatile
# else /* const is not supported */
# define __VOLATILE__
# endif
#endif /* ! defined (__VOLATILE__) */
/*
* Some compilers support the "void" type, but not the semantics of "void *".
*
* The following definition is similar to a usage in System V documentation
* which probably exists for the same reason, except that we use two
* underscores in ours before and after, where theirs is called _VOID.
*
* A word of explanation; what we are doing here is declaring an incomplete
* type; pointers to this incomplete type should function more-or-less as
* a pointer to "void" would except for lacking the implicit conversions that
* are special to "void *", because "void" is an "incomplete type that cannot
* be completed". Read the standard if you don't know about incomplete types.
*/
#ifndef __VOID__
# if __STD_PROFILE__ & __VOIDSTAR_M__
# define __VOID__ void
# else /* void with a pointer is not supported */
# if __COHERENT__ && __MWC__ /* stroke a bug in Coherent 'cc' */
# define __VOID__ char
#else
typedef struct __deep_magic__ __void__;
# define __VOID__ __void__
# endif
# endif
#endif /* ! defined (__VOID__) */
/*
* In order for some of the useful compiler extensions below to be kept
* available during a "strict" compile (assuming that the feature-tests above
* enable their use) then the convention is to prepend compiler-specific
* keywords with double-underscores.
*
* This also serves to document which usages are not ISO C. Note that this
* may have to change a little for a potential standardized C++. Also note
* that as with __NON_POSIX () below, we do not use __CONCAT () but directly
* use whatever style of token-pasting is available to avoid the effects of
* macro-rescanning.
*/
#ifndef __NON_ISO
# if __GNUC__ || __STDC__ + 0
# if __STD_PROFILE__ & __PASTE_M__
# define __NON_ISO(name) __##name
# else
# define __NON_ISO(name) __/**/name
# endif
# else
# define __NON_ISO(k) k
# endif
#endif /* ! defined (__NON_ISO) */
/*
* A feature defined as part of the C++ language that also exists in many
* C implementations is the ability to suppress "argument not used" warnings
* in some cases by omitting the name of the variable in the function
* prototype and merely giving the type.
*
* This feature is common in type-checking compilers since the checking of
* function pointer arguments and other extra checks mean that functions
* must be declared with unused arguments to match the shape of some function
* pointer.
*
* Of course, it is desirable to leave the original name of the variable in
* the same place for documentation purposes, often commented out, but this
* usage chokes some compilers. It seems preferable use the following
* definition to explicitly state the intention, even in cases where the
* compiler generates spurious warnings.
*/
#ifndef __NOTUSED
# if __MISC_PROFILE__ & __NOTUSED_M__
# define __NOTUSED(name) /* name */
# else /* does not understand name suppression */
# define __NOTUSED(name) __CONCAT (unused_, name)
# endif
#endif /* ! defined (__NOTUSED) */
/*
* Most modern compilers perform their own register allocation and ignore
* the "register" directive from K&R C. Such compilers usually have debugging
* tools that know how to deal with variables that spend at least part of
* their lifetime in a machine register (or at worst, the option to suppress
* the auto-register allocation).
*
* For compilers that require a register declaration for a variable to be
* placed in a machine register, often it is desirable to suppress the use
* of registers when debugging.
*
* Of course, most uses of "register" are machine-specific, and using such
* declarations without information gained from profiling is foolish.
*/
#ifndef __REGISTER__
# if __MISC_PROFILE__ & __REGISTER_M__
# define __REGISTER__ register
# else
# define __REGISTER__
# endif
#endif /* ! defined (__REGISTER__) */
/*
* Some compilers for C-like languages such as C++, Objective-C or even
* conceivably Pascal/Modula-2/Fortran support cross-language linkage.
*
* The standard way of doing this within the C family is to use a special
* form of "extern" which names the language a function is implemented in.
* Functions which are implemented in C in a library should be declared as
* such in the exported header.
*
* Currently, this is most important for C++.
*/
#ifndef __EXTERN_C__
# if __MISC_PROFILE__ & __LINKID_M__
# define __EXTERN_C__ extern "C"
# define __EXTERN_C_BEGIN__ __EXTERN_C__ {
# define __EXTERN_C_END__ }
# else /* this is being compiled by a C compiler */
# define __EXTERN_C__
# define __EXTERN_C_BEGIN__
# define __EXTERN_C_END__
# endif
#endif /* ! defined (__EXTERN_C__) */
/*
* All C++ compilers and many C compilers support the notion of "inline
* functions" as an alternative to macros that (i) can be used to wrap up
* casts so they are only used in safe contexts, (ii) can be used as an
* alternative to macros that allow arguments with side-effects.
*
* This comes in two strengths: can inline anything, and can inline anything
* that does not contain a loop. GNU C has extra strength, can inline tail-
* recursive inline function, but that facility is not sufficiently widespread
* to be useful as yet.
*
* The question is, what should the default setting of the client tests be?
* #if ! __NO_INLINE__ is a double-negative, so don't use that. The
* possibility of defining __INLINE__ as "static" so that inline functions
* appear in the module separately breakpointable from other modules is a
* desirable facility (assuming the debug namespace is separate from the
* linkage namespace, likely in a system sophisticated enough to support
* inlining). Furthermore, be aware of any interactions with the __LOCAL__
* macro defined in <common/xdebug.h>
*/
#ifndef __INLINE__
# if __MISC_PROFILE__ & __INLINE_M__
# if __cplusplus
# define __INLINE__ inline
# else
# define __INLINE__ __NON_ISO (inline)
# endif
# define __USE_INLINE__ 1
# else
# define __INLINE__
# endif
#endif
#ifndef __INLINEL__
# if __MISC_PROFILE__ & __INLINEL_M__
# define __INLINEL__ __NON_ISO (inline)
# define __USE_INLINEL__ 1
# else
# define __INLINEL__
# endif
#endif
/*
* One particular incompatibility between ANSI C and C++ code exists in the
* way in which prototypes which do not specify any types at all are handled.
* Under C++, the () form is used to imply (void), since such declarations
* are extremely common and because early versions of the C++ translators did
* not allow any declarations in the argument lists of constructors or
* destructors, not even void, so this form was used to syntactically imply
* (void).
*
* The ANSI C committe declared that a prototype of the form
* extern char * malloc ();
* said nothing whatsoever about the types of it's arguments, since such
* declarations were extremely common in K&R C code, and doing anything else
* would gratuitously require considerable rewriting.
*
* Unfortunately, the ANSI C committee decided that the special form "..." to
* introduce variable arguments was not valid unless preceeded by a regular
* argument type declaration, so that there is no way of being unambiguous
* that will compile under both transators.
*
* ANSI C++
*
* () (...) (void) ambiguous
*
* (void) (void) (void) unambiguous
*
* (...) error (...) thanks, X3J11
*
* Use the preprocessor symbol __ANY_ARGS__ in this context to expand to
* whatever the current translator needs to see for it to make no assumptions
* about the number and type of any function arguments.
*/
#ifndef __ANY_ARGS__
# if __MISC_PROFILE__ & __DOTDOTDOT__
# define __ANY_ARGS__ ...
# else
# define __ANY_ARGS__
# endif
#endif /* ! defined (__ANY_ARGS__) */
/*
* String constants have been mightily botched in C, largely because K&R C
* always treated strings as unique, writeable data. The introduction of the
* 'const' qualifier should have made things simpler by allowing compilers to
* figure out whether a string is being used in a 'const' or non-'const'
* way. However, the precedent of just making all strings which are not being
* used as character array initializers into shareable constants has already
* been established.
*
* This has an effect on complex macros, because a string in a macro may
* cause a host of anonymous, identical string constants to be created, which
* have to be suppressed by using a static declaration. On the other hand,
* this does worse than a compiler which does share strings, because if the
* macro is not actually used then the data space is still taken up.
*
* Here we give a hint to those macros that care.
*/
#ifndef _SHARED_STRINGS
# if (__MISC_PROFILE__ & __NOMERGESTR_M__) == 0
# define _SHARED_STRINGS 1
# endif
#endif /* ! defined (_SHARED_STRINGS) */
/*
* The use of anonymous unions in C++ greatly simplifies the problems caused
* by attempts to forward structure tags into unions with use of #define. This
* use of unions is the primary reason why names which would normally be
* properly scope-controlled in C are given over to the preprocessor to wreak
* havok globally.
*
* Below, we expand __ANON__ into empty if such items need no tag, and
* leave it undefined otherwise, and make _ANONYMOUS a feature-test .
*/
#ifndef _ANONYMOUS
# if (__MISC_PROFILE__ & __ANONUNION_M__) != 0
# define __ANONYMOUS__
# define _ANONYMOUS 1
# endif
#endif
/*
* It is frequently convenient to be able to map a pointer to a member of a
* structure back to a pointer to the parent structure. Unfortunately, while
* ISO C mandates that conversions between pointer types and will not cause
* loss of information, there are few things that can portably be done with
* such a converted pointer. In particular, the easy way of mapping back from
* a structure member pointer to the containing structure performs address
* arithmetic on character pointers using offsetof (). It appears that this
* puts us in the realm of implementation-defined behaviour, except when the
* offsetof () the member is 0.
*/
#ifndef __DOWNCAST
# define __DOWNCAST(str,mem,ptomem) \
((str *) ((char *) (ptomem) - \
__offsetof (str, mem)))
#endif
/*
* This is a minor K&R compatibility issue: certain K&R compilers reject the
* ISO C idiom of enclosing a macro name in parentheses to suppress macro
* expansion when this idiom is used in function declarations. To get around
* this, we can use the ISO preprocessor in a clumsy fashion by providing an
* identity macro to provide the same overall effect of making the name we
* wish to suppress expansion for not be immediately followed by a left
* parenthesis (it will be followed by a parenthesis eventually, but since the
* proprocessor won't revisit the text it has seen before the expansion of
* the identity macro we get the behaviour we want).
*/
#define __ARGS(x) x
/*
* The POSIX.1 standard discusses a special namespace issue; how can standard
* structures be portably extended, given that the structure tags are in the
* user namespace. For structures which have members with regular names and
* which are likely to be extended, the POSIX.1 standard deals with this by
* implicitly reserving all names of that form (something which further
* underscores the restrictions on standard headers not including each other).
*
* However, for situations where we wish to extend a structure not covered by
* the namespace reservation rules, or we wish to name a member according to
* some other usage, we must take care to not define the member such that it
* might conflict with some macro name which the user is permitted to define.
* See POSIX.1 B.2.7.2 for discussion of this point.
*
* The following definition can be used to wrap the definition of structure
* member names such that those names will not conflict with user macros if
* _POSIX_SOURCE is defined, or if _POSIX_C_SOURCE is defined. This form can
* be used in references to the member name which may be encapsulated in
* macros so that there is no loss of functionality or alteration of behaviour
* when POSIX compilation is used.
*
* Note that we do not use __CONCAT () here; the aim of this is to not cause
* accidental conflicts with user-defined macros, but using __CONCAT () would
* result in an extra layer of macro processing, causing the "name" argument
* to be expanded anyway.
*/
#if _POSIX_C_SOURCE
# if __STD_PROFILE__ & __PASTE_M__
# define __NON_POSIX(name) __##name
# else
# define __NON_POSIX(name) __/**/name
# endif
#else
# define __NON_POSIX(name) name
#endif
/*
* GCC has a special feature for declaring functions as not ever returning.
* Also note that GCC versions from 2.5.x support an alternate syntax for this
* operation, __attribute ((noreturn)), which we will support migration to.
*/
#if __IS_GCC_FROM (2, 5)
# define __NO_RETURN__ void
# if ! __cplusplus
# define __NO_RETURN_ATTR__ __attribute__ ((noreturn))
# else
# define __NO_RETURN_ATTR__
# endif
#elif __GNUC__ && ! __PEDANTIC__
# define __NO_RETURN__ __VOLATILE__ void
# define __NO_RETURN_ATTR__
#else
# define __NO_RETURN__ void
# define __NO_RETURN_ATTR__
#endif
/*
* With some systems, structure alignment is configured as a compiler global
* via #pragma, whereas GCC deals with alignment on a per-item basic via
* keyword extensions. The GCC way is preferable (since #pragma is not only
* non-portable, it can't be conditionally wrapped in a macro) and so we wrap
* it up in a macro.
*
* Note that in GCC, the maximum member alignment determines the size to which
* the structure is rounded. Coherent 'cc' instead pads structures based on the
* largest default alignment, ignoring the actual item alignment; if a non-
* default alignment is in effect at the end of the structure (the exact way
* to do that is not defined, but at the moment that is the alignment in
* effect at the next token *after* the '}' at the end of the structure), then
* that alignment is used as the amount to round the structure size to.
*
* Furthermore, GCC aligns structures based on the strictest actual alignment
* of any member. Coherent 'cc' aligns structures based on the strictest
* *default* alignment of any member, and this can only be overridden when the
* structure is later used.
*/
#if __IS_GCC_FROM (2, 3)
# define __ALIGN(n) __attribute__ ((packed, aligned (n)))
#else
# define __ALIGN(n)
#endif
/*
* A feature of both GCC and many "lint" packages is the ability to specify
* that a user-defined function should have special type-checking based on a
* printf () or scanf () format string.
*/
#if __IS_GCC_FROM (2, 3)
# define __PRINTF_LIKE(fmt, first) \
__attribute__ ((format (printf, fmt, first)))
# define __SCANF_LIKE(fmt, first) \
__attribute__ ((format (scanf, fmt, first)))
#else
# define __PRINTF_LIKE(fmt, first)
# define __SCANF_LIKE(fmt, first)
#endif
/*
* GNU C provides a special built-in primitive for returning the alignment
* requirements of any object. In the absence of this, we can reasonably
* safely derive an alignment estimate for any type using a similar trick to
* that commonly used to implement offsetof ()... namely, to compute the
* offsetof () a member of the required type embedded in a structure preceded
* by a single character member.
*
* Note that C++ does not permit type declarations to appear embedded inside
* expressions, so that C expression for this is not valid C++. However, one
* can use templates to gain the equivalent effect.
*/
#if __GNUC__
# define __ALIGNOF(type) __alignof (type)
#elif __cplusplus
template <class T> class __alignof {
private:
struct _foo {
char _a;
T _b;
};
public:
static __size_t _align () { return __offsetof (_foo, _b); }
};
# define __ALIGNOF(type) (__alignof <type> :: _align ())
#else
# define __ALIGNOF(type) \
__offsetof (struct { char _a; type _b; }, _b)
#endif
/*
* Undefine all our internal symbols... why pollute the namespace?
*/
#undef __STRINGIZE_M__
#undef __PASTE_M__
#undef __PROTODECL_M__
#undef __PROTODEFN_M__
#undef __CONST_M__
#undef __VOLATILE_M__
#undef __VOIDSTAR_M__
#undef __STD_PROFILE_MASK__
#undef __NOTUSED_M__
#undef __REGISTER_M__
#undef __LINKID_M__
#undef __INLINE_M__
#undef __INLINEL_M__
#undef __DOTDOTDOT_M__
#undef __NOMERGESTR_M__
#undef __MISC_PROFILE_MASK__
#undef __STDC_M__
#undef __PROFILE__
#undef __STD_PROFILE__
#undef __MISC_PROFILE__
#endif /* ! defined (__COMMON__CCOMPAT_H__) */