|
|
1.1 ! root 1: /* ! 2: * /usr/include/sys/ccompat.h ! 3: * ! 4: * C compiler compatibility definitions. ! 5: * ! 6: * Revised: Wed May 19 10:30:25 1993 CDT ! 7: */ ! 8: #ifndef __SYS_CCOMPAT_H__ ! 9: #define __SYS_CCOMPAT_H__ ! 10: ! 11: /* ! 12: * Define some handy things that allow us to work with K&R, ANSI and C++ ! 13: * compilers in a way that is at least less painful than not working. This ! 14: * file does mandate an ANSI C pre-processing environment. ! 15: * ! 16: * While ANSI allows us to not define function prototypes, C++ mandates that ! 17: * they exist, and it's a *really* good idea to use them whereever possible. ! 18: * ! 19: * This file also deals with some compiler-specific features that are either ! 20: * in the C or C++ language standards but not always available, and some ! 21: * language extensions that are very widely available, if only because they ! 22: * are part of the C++ standard and have been incorporated into C compilers. ! 23: * ! 24: * This file specifically excludes specifics about target machines and ! 25: * compiler interactions. Such definitions belong in another file. ! 26: */ ! 27: ! 28: /* ! 29: * The following ISO-ism has been included in this header as the most ! 30: * logical place. This pair of macros are used to get the *value* of a ! 31: * preprocessor macro stringized, rather than the *name* of the macro. ! 32: * As mentioned above, this file deals with compiler dependencies, and ! 33: * assumes an ANSI preprocessor. Should this have to change, remember to ! 34: * change this. ! 35: * ! 36: * This usage follows PJ Plauger's <assert.h> in "The Standard C Library". ! 37: */ ! 38: ! 39: #define __STR(x) __VAL(x) ! 40: #define __VAL(x) #x ! 41: ! 42: ! 43: /* ! 44: * The Mark Williams Company C compiler on the Coherent operating system for ! 45: * some reason uses symbols in the user's name space to internally identify ! 46: * itself. Here we work around that. ! 47: */ ! 48: ! 49: #if defined (COHERENT) && defined (MWC) && defined (_I386) ! 50: ! 51: /* #undef COHERENT */ ! 52: /* #undef MWC */ ! 53: ! 54: #define __COHERENT__ 1 ! 55: #define __MWC__ 1 ! 56: ! 57: #endif ! 58: ! 59: ! 60: /* ! 61: * There is some complexity on the way __STDC__ is used in practice: the ANSI ! 62: * committee merely says that if __STDC__ is defined and value 1, then the ! 63: * implementation is ISO-conforming. ! 64: * ! 65: * Unfortunately, much existing code uses #ifdef as the only test, which ! 66: * means that some non-conforming compilers which defined __STDC__ as zero ! 67: * caused problems (the Coherent 3.x compiler is one such; the 4.x compiler ! 68: * uses the alternate convention). The #if test is preferable in programs, ! 69: * since in preprocessor tests undefined symbols assume value 0, but still ! 70: * many programs use the alternate form. ! 71: * ! 72: * For compilers with an intermediate status, eg. with an ISO preprocessor, ! 73: * or support for "const" but not prototypes, or prototypes but not "const" ! 74: * we perform individual featurectomies below. ! 75: * ! 76: * A general rule for future extensions: use double-underscores before and ! 77: * after for non-parameterized macros, double-underscores before for macros ! 78: * that take parameters. If this file's definitions are to be used by user- ! 79: * level code, create a header that exports the definitions into the user ! 80: * namespace. ! 81: */ ! 82: ! 83: #define __PROTODECL_M__ 0x0001 /* supports prototype declarations */ ! 84: #define __PROTODEFN_M__ 0x0002 /* supports prototype definitions */ ! 85: #define __CONST_M__ 0x0004 /* supports "const" construct */ ! 86: #define __VOLATILE_M__ 0x0008 /* supports "volatile" construct */ ! 87: #define __VOIDSTAR_M__ 0x0010 /* supports "void *" type */ ! 88: ! 89: #define __NOTUSED_M__ 0x0100 /* allows "not used" warning suppression */ ! 90: #define __REGISTER_M__ 0x0200 /* requires "register" declaration */ ! 91: #define __LINKID_M__ 0x0400 /* requires linkage specifier (eg C++) */ ! 92: #define __INLINE_M__ 0x0800 /* allows inline functions */ ! 93: #define __INLINEL_M__ 0x1000 /* allows inline functions with loops */ ! 94: #define __DOTDOTDOT__ 0x2000 /* requires (...) rather than () */ ! 95: ! 96: ! 97: /* ! 98: * The Standard C language features in one definition for simplicity. ! 99: */ ! 100: ! 101: #define __STDC_M__ (__PROTODECL_M__ | __PROTODEFN_M__ | __CONST_M__ | \ ! 102: __VOLATILE_M__ | __VOIDSTAR_M__) ! 103: ! 104: ! 105: /* ! 106: * Below, we attempt to determine a configuration suitable for the translator ! 107: * that is working on the current program. Each group of macros attempts to ! 108: * set a preprocessor macro __PROFILE__ with a bit-mask of the features ! 109: * supported by the current translator. ! 110: * ! 111: * This approach has been taken since it considerably simplifies both the ! 112: * task of adding new features to test for and adding new translators. Many ! 113: * other programs intermingle the tasks of determining the translator and ! 114: * defining the responses to that determination; in general, such programs ! 115: * fail to be maintainable when the matrix of features and translators grows ! 116: * larger than about 3x3. ! 117: */ ! 118: ! 119: #if defined (__PROFILE__) /* user-overridden */ ! 120: ! 121: # if (__PROFILE__ & ~ (__STDC_M__ | __NOTUSED_M__ | __REGISTER_M__ | \ ! 122: __LINKID_M__)) != 0 ! 123: # error __PROFILE__ contains unknown flag bits. ! 124: # endif ! 125: ! 126: #elif defined (__cplusplus) /* C++ */ ! 127: ! 128: # ifdef __GNUC__ ! 129: # define __PROFILE__ (__STDC_M__ | __NOTUSED_M__ | __LINKID_M__ | \ ! 130: __INLINE_M__ | __INLINEL_M__ | __DOTDOTDOT__) ! 131: # else ! 132: # define __PROFILE__ (__STDC_M__ | __NOTUSED_M__ | __LINKID_M__ | \ ! 133: __INLINE_M__ | __DOTDOTDOT__) ! 134: # endif ! 135: ! 136: #elif defined (__BORLANDC__) /* Borland C */ ! 137: ! 138: # if __BORLANDC__ >= 0x410 ! 139: # define __PROFILE__ (__STDC_M__) /* features restricted to C++ */ ! 140: # else ! 141: # define __PROFILE__ (__STDC_M__ | __NOTUSED_M__ | __INLINE_M__) ! 142: # endif ! 143: ! 144: #elif defined (__GNUC__) /* GCC w/o C */ ! 145: ! 146: # define __PROFILE__ (__STDC_M__ | __INLINE_M__ | __INLINEL_M__) ! 147: ! 148: #elif defined (__STDC__) && (__STDC__ == 1) /* minimal ANSI C */ ! 149: ! 150: # define __PROFILE__ (__STDC_M__) ! 151: ! 152: #elif defined (__COHERENT__) /* MWC Coherent */ ! 153: ! 154: # define __PROFILE__ (__REGISTER_M__) ! 155: ! 156: #else /* VANILLA */ ! 157: ! 158: # define __PROFILE__ (__REGISTER_M__) ! 159: ! 160: #endif ! 161: ! 162: ! 163: /* ! 164: * In the following sections we determine the responses to take on the basis ! 165: * of whether or not each feature/misfeature is supported by the current ! 166: * translator. ! 167: * ! 168: * In cases where the feature requires considerable change to source code, ! 169: * such as prototyping and inline functions, we define both an existence test ! 170: * name (which should be tested for definition, not value) and a value macro. ! 171: * For the case of inline functions, this is because the function should not ! 172: * appear at all in the souce code unless unlining is supported (and because ! 173: * often a macro may suffice in place, although with less safety). ! 174: * ! 175: * In addition, the tests below always check to see whether a particular ! 176: * symbol is defined already, allowing almost any feature to be turned on or ! 177: * off at will from the command-line. This is useful when testing the ! 178: * characteristics of a new translator, and may often be useful to suppress ! 179: * certain features to aid in debugging. ! 180: */ ! 181: ! 182: /* ! 183: * __PROTO__ is a general test which can be performed in .c files to see ! 184: * whether to use a prototype form or a K&R form, since the two are so ! 185: * different. This has the advantage that some tools which are hard-wired for ! 186: * K&R source code can get confused by macros in the function header, so ! 187: * keeping a real K&R header around can help. ! 188: * ! 189: * __PROTO () is a macro that can be used in header files, since all that ! 190: * differs between K&R and ANSI external definitions is whether the types ! 191: * are present. ! 192: * ! 193: * The difference between the two is important, especially when "lint"-like ! 194: * tools are used. In order to check for consistency between the prototype ! 195: * and K&R-style definitions, it may be necessary to enable prototypes in ! 196: * the header files while suppressing them in the C files. ! 197: */ ! 198: ! 199: #ifndef __PROTO ! 200: # if (__PROFILE__ & __PROTODECL_M__) != 0 ! 201: ! 202: # define __PROTO(p) p ! 203: ! 204: # else /* prototypes are not supported */ ! 205: ! 206: # define __PROTO(p) () ! 207: ! 208: # endif ! 209: # if (__PROFILE__ & __PROTODEFN_M__) != 0 ! 210: ! 211: # define __USE_PROTO__ ! 212: ! 213: # endif ! 214: #endif /* ! defined (__PROTO) */ ! 215: ! 216: ! 217: /* ! 218: * There are several existing compilers still in use which either do not ! 219: * support the notion of a "const" language element or implement the feature ! 220: * incorrectly with respect to the C standard. ! 221: * ! 222: * For these compilers, we allow the "const" specifier in prototypes, local ! 223: * variables and structure declarations to be suppressed. Note that "const" ! 224: * will never appear in a K&R function header. ! 225: */ ! 226: ! 227: #ifndef __CONST__ ! 228: # if (__PROFILE__ & __CONST_M__) != 0 ! 229: ! 230: # define __CONST__ const ! 231: ! 232: # else /* const is not supported */ ! 233: ! 234: # define __CONST__ ! 235: ! 236: # endif ! 237: #endif /* ! defined (__CONST__) */ ! 238: ! 239: ! 240: /* ! 241: * For symmetry with the "const" definition, we provide a wrapper for the ! 242: * "volatile" feature. Note that for some reason "volatile" is available in ! 243: * some compilers that do not implement "const", probably because the feature ! 244: * was defined in simpler terms. ! 245: * ! 246: * For these compilers, we allow the "volatile" specifier in prototypes, ! 247: * local variables, and structure declarations to be suppressed. ! 248: */ ! 249: ! 250: #ifndef __VOLATILE__ ! 251: # if (__PROFILE__ & __VOLATILE_M__) != 0 ! 252: ! 253: # define __VOLATILE__ volatile ! 254: ! 255: # else /* const is not supported */ ! 256: ! 257: # define __VOLATILE__ ! 258: ! 259: # endif ! 260: #endif /* ! defined (__VOLATILE__) */ ! 261: ! 262: ! 263: /* ! 264: * Some compilers support the "void" type, but not the semantics of "void *". ! 265: * ! 266: * The following definition is similar to a usage in System V documentation ! 267: * which probably exists for the same reason, except that we use two ! 268: * underscores in ours before and after, where theirs is called _VOID. ! 269: */ ! 270: ! 271: #ifndef __VOID__ ! 272: # if (__PROFILE__ & __VOIDSTAR_M__) != 0 ! 273: ! 274: # define __VOID__ void ! 275: ! 276: # else /* void with a pointer is not supported */ ! 277: ! 278: # define __VOID__ unsigned char ! 279: ! 280: # endif ! 281: #endif /* ! defined (__VOID__) */ ! 282: ! 283: ! 284: /* ! 285: * A feature defined as part of the C++ language that also exists in many ! 286: * C implementations is the ability to suppress "argument not used" warnings ! 287: * in some cases by omitting the name of the variable in the function ! 288: * prototype and merely giving the type. ! 289: * ! 290: * This feature is common in type-checking compilers since the checking of ! 291: * function pointer arguments and other extra checks mean that functions ! 292: * must be declared with unused arguments to match the shape of some function ! 293: * pointer. ! 294: * ! 295: * Of course, it is desirable to leave the original name of the variable in ! 296: * the same place for documentation purposes, often commented out, but this ! 297: * usage chokes some compilers. It seems preferable use the following ! 298: * definition to explicitly state the intention, even in cases where the ! 299: * compiler generates spurious warnings. ! 300: */ ! 301: ! 302: #ifndef __NOTUSED ! 303: # if (__PROFILE__ & __NOTUSED_M__) != 0 ! 304: ! 305: # define __NOTUSED(name) /* name */ ! 306: ! 307: # else /* does not understand name suppression */ ! 308: ! 309: # define __NOTUSED(name) name ! 310: ! 311: # endif ! 312: #endif /* ! defined (__NOTUSED) */ ! 313: ! 314: ! 315: /* ! 316: * Most modern compilers perform their own register allocation and ignore ! 317: * the "register" directive from K&R C. Such compilers usually have debugging ! 318: * tools that know how to deal with variables that spend at least part of ! 319: * their lifetime in a machine register (or at worst, the option to suppress ! 320: * the auto-register allocation). ! 321: * ! 322: * For compilers that require a register declaration for a variable to be ! 323: * placed in a machine register, often it is desirable to suppress the use ! 324: * of registers when debugging. ! 325: */ ! 326: ! 327: #ifndef __REGISTER__ ! 328: # if (__PROFILE__ & __REGISTER_M__) != 0 ! 329: ! 330: # define __REGISTER__ register ! 331: ! 332: # else ! 333: ! 334: # define __REGISTER__ ! 335: ! 336: # endif ! 337: #endif /* ! defined (__REGISTER__) */ ! 338: ! 339: ! 340: /* ! 341: * Some compilers for C-like languages such as C++, Objective-C or even ! 342: * conceivably Pascal/Modula-2/Fortran support cross-language linkage. ! 343: * ! 344: * The standard way of doing this within the C family is to use a special ! 345: * form of "extern" which names the language a function is implemented in. ! 346: * Functions which are implemented in C in a library should be declared as ! 347: * such in the exported header. ! 348: * ! 349: * Currently, this is most important for C++. ! 350: */ ! 351: ! 352: #ifndef __EXTERN_C__ ! 353: # if (__PROFILE__ & __LINKID_M__) != 0 ! 354: ! 355: # define __EXTERN_C__ extern "C" ! 356: # define __EXTERN_C_BEGIN__ __EXTERN_C__ { ! 357: # define __EXTERN_C_END__ } ! 358: ! 359: # else /* this is being compiled by a C compiler */ ! 360: ! 361: # define __EXTERN_C__ ! 362: # define __EXTERN_C_BEGIN__ ! 363: # define __EXTERN_C_END__ ! 364: ! 365: # endif ! 366: #endif /* ! defined (__EXTERN_C__) */ ! 367: ! 368: ! 369: /* ! 370: * In order for some of the useful compiler extensions below to be kept ! 371: * available during a "strict" compile (assuming that the feature-tests above ! 372: * enable their use) then the convention is to prepend compiler-specific ! 373: * keywords with double-underscores. ! 374: * ! 375: * This also serves to document which usages are not ISO C. Note that this ! 376: * may have to change a little for a potential standardized C++. ! 377: */ ! 378: ! 379: #if defined (__STDC__) && __STDC__ != 0 ! 380: ! 381: # define __NON_ISO(k) __##k ! 382: ! 383: #else ! 384: ! 385: # define __NON_ISO(k) k ! 386: ! 387: #endif ! 388: ! 389: ! 390: /* ! 391: * All C++ compilers and many C compilers support the notion of "inline ! 392: * functions" as an alternative to macros that (i) can be used to wrap up ! 393: * casts so they are only used in safe contexts, (ii) can be used as an ! 394: * alternative to macros that allow arguments with side-effects. ! 395: * ! 396: * This comes in two strengths: can inline anything, and can inline anything ! 397: * that does not contain a loop. GNU C has extra strength, can inline tail- ! 398: * recursive inline function, but that facility is not sufficiently widespread ! 399: * to be useful as yet. ! 400: * ! 401: * The question is, what should the default setting of the client tests be? ! 402: * I prefer #ifndef __NO_INLINE__, since by default I want to be getting all ! 403: * the features. The possibility of defining __INLINE__ as "static" so that ! 404: * inline functions appear in the module separately breakpointable from other ! 405: * modules is a desirable facility (assuming the debug namespace is separate ! 406: * from the linkage namespace, likely in a system sophisticated enough to ! 407: * support inlining). Furthermore, be aware of any interactions with the ! 408: * __LOCAL__ macro defined in <sys/xdebug.h> ! 409: */ ! 410: ! 411: #if ! defined (__NO_INLINE__) && ! defined (__INLINE__) ! 412: # if (__PROFILE__ & __INLINE_M__) != 0 ! 413: ! 414: # define __INLINE__ __NON_ISO (inline) ! 415: ! 416: # if ! defined (__NO_INLINEL__) && ! defined (__INLINEL__) ! 417: # if (__PROFILE__ & __INLINEL_M__) != 0 ! 418: ! 419: # define __INLINEL__ __NON_ISO (inline) ! 420: ! 421: # else ! 422: ! 423: # define __INLINEL__ ! 424: # define __NO_INLINEL__ ! 425: ! 426: # endif ! 427: # endif /* ! defined (__NO_INLINEL__) && ! defined (__INLINEL__) */ ! 428: ! 429: # else /* does not grok inlining */ ! 430: ! 431: # define __INLINE__ ! 432: # define __NO_INLINE__ ! 433: ! 434: # endif ! 435: ! 436: #else /* if the user has overridden __NO_INLINE__ or __INLINE__ */ ! 437: ! 438: #endif /* defined (__NO_INLINE__) || defined (__INLINE__) */ ! 439: ! 440: ! 441: /* ! 442: * One particular incompatibility between ANSI C and C++ code exists in the ! 443: * way in which prototypes which do not specify any types at all are handled. ! 444: * Under C++, the () form is used to imply (void), since such declarations ! 445: * are extremely common and because early versions of the C++ translators did ! 446: * not allow any declarations in the argument lists of constructors or ! 447: * destructors, not even void, so this form was used to syntactically imply ! 448: * (void). ! 449: * ! 450: * The ANSI C committe declared that a prototype of the form ! 451: * extern char * malloc (); ! 452: * said nothing whatsoever about the types of its arguments, since such ! 453: * declarations were extremely common in K&R C code, and doing anything else ! 454: * would gratuitously require considerable rewriting. ! 455: * ! 456: * Unfortunately, the ANSI C committee decided that the special form "..." to ! 457: * introduce variable arguments was not valid unless preceeded by a regular ! 458: * argument type declaration, so that there is no way of being unambiguous ! 459: * that will compile under both transators. ! 460: * ! 461: * ANSI C++ ! 462: * ! 463: * () (...) (void) ambiguous ! 464: * ! 465: * (void) (void) (void) unambiguous ! 466: * ! 467: * (...) error (...) thanks, X3J11 ! 468: * ! 469: * Use the preprocessor symbol __ANY_ARGS__ in this context to expand to ! 470: * whatever the current translator needs to see for it to make no assumptions ! 471: * about the number and type of any function arguments. ! 472: */ ! 473: ! 474: #ifndef __ANY_ARGS__ ! 475: # if (__PROFILE__ & __DOTDOTDOT__) != 0 ! 476: ! 477: # define __ANY_ARGS__ ... ! 478: ! 479: # else ! 480: ! 481: # define __ANY_ARGS__ ! 482: ! 483: # endif ! 484: #endif /* ! defined (__ANY_ARGS__) */ ! 485: ! 486: ! 487: /* ! 488: * This is a minor K&R compatibility issue: certain K&R compilers reject the ! 489: * ISO C idiom of enclosing a macro name in parentheses to suppress macro ! 490: * expansion when this idiom is used in function declarations. To get around ! 491: * this, we can use the ISO preprocessor in a clumsy fashion by providing an ! 492: * identity macro to provide the same overall effect of making the name we ! 493: * wish to suppress expansion for not be immediately followed by a left ! 494: * parenthesis (it will be followed by parenthesis eventually, but since the ! 495: * proprocessor won't revisit the text it has seen before the expansion of ! 496: * the identity macro we get the behaviour we want). ! 497: */ ! 498: ! 499: #define __ARGS(x) x ! 500: ! 501: ! 502: /* ! 503: * The C standard recommends that a system have a method of selecting a "pure" ! 504: * compilation environment, but leaves the method for doing so up to the ! 505: * implementation. For our headers we will define a feature-test macro along ! 506: * the lines of the POSIX.1 feature-test. ! 507: * ! 508: * If _STDC_SOURCE is defined with a non-zero value, we interpret that as ! 509: * meaning that the user wishes a pure compilation environment with no symbols ! 510: * in the user name-space visible in headers other than those defined in the ! 511: * ISO C standard ISO/IEC 9899:1990. ! 512: * ! 513: * This flag cannot be used with the _POSIX_SOURCE flag; the symbols defined ! 514: * by headers in the POSIX.1 standard ISO/IEC 9945-1:1990 are a superset of ! 515: * those defined by the C standard, so if _POSIX_SOURCE is specified we ! 516: * undefine _STDC_SOURCE. ! 517: */ ! 518: ! 519: #if defined(_POSIX_SOURCE) ! 520: #undef _STDC_SOURCE ! 521: #endif ! 522: ! 523: ! 524: /* ! 525: * The POSIX.1 standard discusses a special namespace issue; how can standard ! 526: * structures be portably extended, given that the structure tags are in the ! 527: * user namespace. For structures which have members with regular names and ! 528: * which are likely to be extended, the POSIX.1 standard deals with this by ! 529: * implicitly reserving all names of that form (something which further ! 530: * underscores the restrictions on standard headers not including each other). ! 531: * ! 532: * However, for situations where we wish to extend a structure not covered by ! 533: * the namespace reservation rules, or we wish to name a member according to ! 534: * some other usage, we must take care to not define the member such that it ! 535: * might conflict with some macro name which the user is permitted to define. ! 536: * See POSIX.1 B.2.7.2 for discussion of this point. ! 537: * ! 538: * The following definition can be used to wrap the definition of structure ! 539: * member names such that those names will not conflict with user macros if ! 540: * _POSIX_SOURCE is defined. This form can be used in references to the member ! 541: * name which may be encapsulated in macros so that there is no loss of ! 542: * functionality or alteration of behaviour when _POSIX_SOURCE is used. ! 543: */ ! 544: ! 545: #if defined(_POSIX_SOURCE) ! 546: ! 547: # define __NON_POSIX(name) _##name ! 548: ! 549: #else ! 550: ! 551: # define __NON_POSIX(name) name ! 552: ! 553: #endif ! 554: ! 555: ! 556: /* ! 557: * Undefine all our internal symbols... why pollute the namespace? ! 558: */ ! 559: ! 560: #undef __PROTO_M__ ! 561: #undef __CONST_M__ ! 562: #undef __VOLATILE_M__ ! 563: #undef __VOIDSTAR_M__ ! 564: ! 565: #undef __NOTUSED_M__ ! 566: #undef __REGISTER_M__ ! 567: #undef __LINKID_M__ ! 568: #undef __INLINE_M__ ! 569: #undef __INLINEL_M__ ! 570: #undef __DOTDOTDOT__ ! 571: ! 572: #undef __STDC_M__ ! 573: #undef __PROFILE__ ! 574: ! 575: ! 576: #endif /* ! defined (__SYS_CCOMPAT_H__) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.