1*e992f068Schristos /* Compiler compatibility macros 2*e992f068Schristos Copyright (C) 1991-2022 Free Software Foundation, Inc. 375fd0b74Schristos This file is part of the GNU C Library. 475fd0b74Schristos 575fd0b74Schristos This program is free software; you can redistribute it and/or modify 675fd0b74Schristos it under the terms of the GNU General Public License as published by 775fd0b74Schristos the Free Software Foundation; either version 2 of the License, or 875fd0b74Schristos (at your option) any later version. 975fd0b74Schristos 1075fd0b74Schristos This program is distributed in the hope that it will be useful, 1175fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1275fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1375fd0b74Schristos GNU General Public License for more details. 1475fd0b74Schristos 1575fd0b74Schristos You should have received a copy of the GNU General Public License 1675fd0b74Schristos along with this program; if not, write to the Free Software 1775fd0b74Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 1875fd0b74Schristos 19*e992f068Schristos /* For ease of writing code which uses GCC extensions but needs to be 2075fd0b74Schristos portable to other compilers, we provide the GCC_VERSION macro that 2175fd0b74Schristos simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various 2275fd0b74Schristos wrappers around __attribute__. Also, __extension__ will be #defined 2375fd0b74Schristos to nothing if it doesn't work. See below. */ 2475fd0b74Schristos 2575fd0b74Schristos #ifndef _ANSIDECL_H 2675fd0b74Schristos #define _ANSIDECL_H 1 2775fd0b74Schristos 2875fd0b74Schristos #ifdef __cplusplus 2975fd0b74Schristos extern "C" { 3075fd0b74Schristos #endif 3175fd0b74Schristos 3275fd0b74Schristos /* Every source file includes this file, 3375fd0b74Schristos so they will all get the switch for lint. */ 3475fd0b74Schristos /* LINTLIBRARY */ 3575fd0b74Schristos 3675fd0b74Schristos /* Using MACRO(x,y) in cpp #if conditionals does not work with some 3775fd0b74Schristos older preprocessors. Thus we can't define something like this: 3875fd0b74Schristos 3975fd0b74Schristos #define HAVE_GCC_VERSION(MAJOR, MINOR) \ 4075fd0b74Schristos (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR))) 4175fd0b74Schristos 4275fd0b74Schristos and then test "#if HAVE_GCC_VERSION(2,7)". 4375fd0b74Schristos 4475fd0b74Schristos So instead we use the macro below and test it against specific values. */ 4575fd0b74Schristos 4675fd0b74Schristos /* This macro simplifies testing whether we are using gcc, and if it 4775fd0b74Schristos is of a particular minimum version. (Both major & minor numbers are 4875fd0b74Schristos significant.) This macro will evaluate to 0 if we are not using 4975fd0b74Schristos gcc at all. */ 5075fd0b74Schristos #ifndef GCC_VERSION 5175fd0b74Schristos #define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) 5275fd0b74Schristos #endif /* GCC_VERSION */ 5375fd0b74Schristos 5475fd0b74Schristos /* inline requires special treatment; it's in C99, and GCC >=2.7 supports 5575fd0b74Schristos it too, but it's not in C89. */ 5675fd0b74Schristos #undef inline 57*e992f068Schristos #if (!defined(__cplusplus) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__)) 5875fd0b74Schristos /* it's a keyword */ 5975fd0b74Schristos #else 6075fd0b74Schristos # if GCC_VERSION >= 2007 6175fd0b74Schristos # define inline __inline__ /* __inline__ prevents -pedantic warnings */ 6275fd0b74Schristos # else 6375fd0b74Schristos # define inline /* nothing */ 6475fd0b74Schristos # endif 6575fd0b74Schristos #endif 6675fd0b74Schristos 6775fd0b74Schristos /* Define macros for some gcc attributes. This permits us to use the 6875fd0b74Schristos macros freely, and know that they will come into play for the 6975fd0b74Schristos version of gcc in which they are supported. */ 7075fd0b74Schristos 7175fd0b74Schristos #if (GCC_VERSION < 2007) 7275fd0b74Schristos # define __attribute__(x) 7375fd0b74Schristos #endif 7475fd0b74Schristos 7575fd0b74Schristos /* Attribute __malloc__ on functions was valid as of gcc 2.96. */ 7675fd0b74Schristos #ifndef ATTRIBUTE_MALLOC 7775fd0b74Schristos # if (GCC_VERSION >= 2096) 7875fd0b74Schristos # define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) 7975fd0b74Schristos # else 8075fd0b74Schristos # define ATTRIBUTE_MALLOC 8175fd0b74Schristos # endif /* GNUC >= 2.96 */ 8275fd0b74Schristos #endif /* ATTRIBUTE_MALLOC */ 8375fd0b74Schristos 8475fd0b74Schristos /* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For 8575fd0b74Schristos g++ an attribute on a label must be followed by a semicolon. */ 8675fd0b74Schristos #ifndef ATTRIBUTE_UNUSED_LABEL 8775fd0b74Schristos # ifndef __cplusplus 8875fd0b74Schristos # if GCC_VERSION >= 2093 8975fd0b74Schristos # define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED 9075fd0b74Schristos # else 9175fd0b74Schristos # define ATTRIBUTE_UNUSED_LABEL 9275fd0b74Schristos # endif 9375fd0b74Schristos # else 9475fd0b74Schristos # if GCC_VERSION >= 4005 9575fd0b74Schristos # define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ; 9675fd0b74Schristos # else 9775fd0b74Schristos # define ATTRIBUTE_UNUSED_LABEL 9875fd0b74Schristos # endif 9975fd0b74Schristos # endif 10075fd0b74Schristos #endif 10175fd0b74Schristos 10275fd0b74Schristos /* Similarly to ARG_UNUSED below. Prior to GCC 3.4, the C++ frontend 10375fd0b74Schristos couldn't parse attributes placed after the identifier name, and now 10475fd0b74Schristos the entire compiler is built with C++. */ 10575fd0b74Schristos #ifndef ATTRIBUTE_UNUSED 10675fd0b74Schristos #if GCC_VERSION >= 3004 10775fd0b74Schristos # define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) 10875fd0b74Schristos #else 10975fd0b74Schristos #define ATTRIBUTE_UNUSED 11075fd0b74Schristos #endif 11175fd0b74Schristos #endif /* ATTRIBUTE_UNUSED */ 11275fd0b74Schristos 11375fd0b74Schristos /* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the 11475fd0b74Schristos identifier name. */ 11575fd0b74Schristos #if ! defined(__cplusplus) || (GCC_VERSION >= 3004) 11675fd0b74Schristos # define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED 11775fd0b74Schristos #else /* !__cplusplus || GNUC >= 3.4 */ 11875fd0b74Schristos # define ARG_UNUSED(NAME) NAME 11975fd0b74Schristos #endif /* !__cplusplus || GNUC >= 3.4 */ 12075fd0b74Schristos 12175fd0b74Schristos #ifndef ATTRIBUTE_NORETURN 12275fd0b74Schristos #define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) 12375fd0b74Schristos #endif /* ATTRIBUTE_NORETURN */ 12475fd0b74Schristos 12575fd0b74Schristos /* Attribute `nonnull' was valid as of gcc 3.3. */ 12675fd0b74Schristos #ifndef ATTRIBUTE_NONNULL 12775fd0b74Schristos # if (GCC_VERSION >= 3003) 12875fd0b74Schristos # define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m))) 12975fd0b74Schristos # else 13075fd0b74Schristos # define ATTRIBUTE_NONNULL(m) 13175fd0b74Schristos # endif /* GNUC >= 3.3 */ 13275fd0b74Schristos #endif /* ATTRIBUTE_NONNULL */ 13375fd0b74Schristos 13475fd0b74Schristos /* Attribute `returns_nonnull' was valid as of gcc 4.9. */ 13575fd0b74Schristos #ifndef ATTRIBUTE_RETURNS_NONNULL 13675fd0b74Schristos # if (GCC_VERSION >= 4009) 13775fd0b74Schristos # define ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__)) 13875fd0b74Schristos # else 13975fd0b74Schristos # define ATTRIBUTE_RETURNS_NONNULL 14075fd0b74Schristos # endif /* GNUC >= 4.9 */ 14175fd0b74Schristos #endif /* ATTRIBUTE_RETURNS_NONNULL */ 14275fd0b74Schristos 14375fd0b74Schristos /* Attribute `pure' was valid as of gcc 3.0. */ 14475fd0b74Schristos #ifndef ATTRIBUTE_PURE 14575fd0b74Schristos # if (GCC_VERSION >= 3000) 14675fd0b74Schristos # define ATTRIBUTE_PURE __attribute__ ((__pure__)) 14775fd0b74Schristos # else 14875fd0b74Schristos # define ATTRIBUTE_PURE 14975fd0b74Schristos # endif /* GNUC >= 3.0 */ 15075fd0b74Schristos #endif /* ATTRIBUTE_PURE */ 15175fd0b74Schristos 15275fd0b74Schristos /* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL. 15375fd0b74Schristos This was the case for the `printf' format attribute by itself 15475fd0b74Schristos before GCC 3.3, but as of 3.3 we need to add the `nonnull' 15575fd0b74Schristos attribute to retain this behavior. */ 15675fd0b74Schristos #ifndef ATTRIBUTE_PRINTF 15775fd0b74Schristos #define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m) 15875fd0b74Schristos #define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) 15975fd0b74Schristos #define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) 16075fd0b74Schristos #define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4) 16175fd0b74Schristos #define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5) 16275fd0b74Schristos #define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6) 16375fd0b74Schristos #endif /* ATTRIBUTE_PRINTF */ 16475fd0b74Schristos 16575fd0b74Schristos /* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on 16675fd0b74Schristos a function pointer. Format attributes were allowed on function 16775fd0b74Schristos pointers as of gcc 3.1. */ 16875fd0b74Schristos #ifndef ATTRIBUTE_FPTR_PRINTF 16975fd0b74Schristos # if (GCC_VERSION >= 3001) 17075fd0b74Schristos # define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n) 17175fd0b74Schristos # else 17275fd0b74Schristos # define ATTRIBUTE_FPTR_PRINTF(m, n) 17375fd0b74Schristos # endif /* GNUC >= 3.1 */ 17475fd0b74Schristos # define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2) 17575fd0b74Schristos # define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3) 17675fd0b74Schristos # define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4) 17775fd0b74Schristos # define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5) 17875fd0b74Schristos # define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6) 17975fd0b74Schristos #endif /* ATTRIBUTE_FPTR_PRINTF */ 18075fd0b74Schristos 18175fd0b74Schristos /* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A 18275fd0b74Schristos NULL format specifier was allowed as of gcc 3.3. */ 18375fd0b74Schristos #ifndef ATTRIBUTE_NULL_PRINTF 18475fd0b74Schristos # if (GCC_VERSION >= 3003) 18575fd0b74Schristos # define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) 18675fd0b74Schristos # else 18775fd0b74Schristos # define ATTRIBUTE_NULL_PRINTF(m, n) 18875fd0b74Schristos # endif /* GNUC >= 3.3 */ 18975fd0b74Schristos # define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2) 19075fd0b74Schristos # define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3) 19175fd0b74Schristos # define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4) 19275fd0b74Schristos # define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5) 19375fd0b74Schristos # define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6) 19475fd0b74Schristos #endif /* ATTRIBUTE_NULL_PRINTF */ 19575fd0b74Schristos 19675fd0b74Schristos /* Attribute `sentinel' was valid as of gcc 3.5. */ 19775fd0b74Schristos #ifndef ATTRIBUTE_SENTINEL 19875fd0b74Schristos # if (GCC_VERSION >= 3005) 19975fd0b74Schristos # define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__)) 20075fd0b74Schristos # else 20175fd0b74Schristos # define ATTRIBUTE_SENTINEL 20275fd0b74Schristos # endif /* GNUC >= 3.5 */ 20375fd0b74Schristos #endif /* ATTRIBUTE_SENTINEL */ 20475fd0b74Schristos 20575fd0b74Schristos 20675fd0b74Schristos #ifndef ATTRIBUTE_ALIGNED_ALIGNOF 20775fd0b74Schristos # if (GCC_VERSION >= 3000) 20875fd0b74Schristos # define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m)))) 20975fd0b74Schristos # else 21075fd0b74Schristos # define ATTRIBUTE_ALIGNED_ALIGNOF(m) 21175fd0b74Schristos # endif /* GNUC >= 3.0 */ 21275fd0b74Schristos #endif /* ATTRIBUTE_ALIGNED_ALIGNOF */ 21375fd0b74Schristos 214ede78133Schristos /* Useful for structures whose layout must match some binary specification 21575fd0b74Schristos regardless of the alignment and padding qualities of the compiler. */ 21675fd0b74Schristos #ifndef ATTRIBUTE_PACKED 21775fd0b74Schristos # define ATTRIBUTE_PACKED __attribute__ ((packed)) 21875fd0b74Schristos #endif 21975fd0b74Schristos 22075fd0b74Schristos /* Attribute `hot' and `cold' was valid as of gcc 4.3. */ 22175fd0b74Schristos #ifndef ATTRIBUTE_COLD 22275fd0b74Schristos # if (GCC_VERSION >= 4003) 22375fd0b74Schristos # define ATTRIBUTE_COLD __attribute__ ((__cold__)) 22475fd0b74Schristos # else 22575fd0b74Schristos # define ATTRIBUTE_COLD 22675fd0b74Schristos # endif /* GNUC >= 4.3 */ 22775fd0b74Schristos #endif /* ATTRIBUTE_COLD */ 22875fd0b74Schristos #ifndef ATTRIBUTE_HOT 22975fd0b74Schristos # if (GCC_VERSION >= 4003) 23075fd0b74Schristos # define ATTRIBUTE_HOT __attribute__ ((__hot__)) 23175fd0b74Schristos # else 23275fd0b74Schristos # define ATTRIBUTE_HOT 23375fd0b74Schristos # endif /* GNUC >= 4.3 */ 23475fd0b74Schristos #endif /* ATTRIBUTE_HOT */ 23575fd0b74Schristos 23675fd0b74Schristos /* Attribute 'no_sanitize_undefined' was valid as of gcc 4.9. */ 23775fd0b74Schristos #ifndef ATTRIBUTE_NO_SANITIZE_UNDEFINED 23875fd0b74Schristos # if (GCC_VERSION >= 4009) 23975fd0b74Schristos # define ATTRIBUTE_NO_SANITIZE_UNDEFINED __attribute__ ((no_sanitize_undefined)) 24075fd0b74Schristos # else 24175fd0b74Schristos # define ATTRIBUTE_NO_SANITIZE_UNDEFINED 24275fd0b74Schristos # endif /* GNUC >= 4.9 */ 24375fd0b74Schristos #endif /* ATTRIBUTE_NO_SANITIZE_UNDEFINED */ 24475fd0b74Schristos 245ede78133Schristos /* Attribute 'nonstring' was valid as of gcc 8. */ 246ede78133Schristos #ifndef ATTRIBUTE_NONSTRING 247ede78133Schristos # if GCC_VERSION >= 8000 248ede78133Schristos # define ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__)) 249ede78133Schristos # else 250ede78133Schristos # define ATTRIBUTE_NONSTRING 251ede78133Schristos # endif 252ede78133Schristos #endif 253ede78133Schristos 254012573ebSchristos /* Attribute `alloc_size' was valid as of gcc 4.3. */ 255012573ebSchristos #ifndef ATTRIBUTE_RESULT_SIZE_1 256012573ebSchristos # if (GCC_VERSION >= 4003) 257012573ebSchristos # define ATTRIBUTE_RESULT_SIZE_1 __attribute__ ((alloc_size (1))) 258012573ebSchristos # else 259012573ebSchristos # define ATTRIBUTE_RESULT_SIZE_1 260012573ebSchristos #endif 261012573ebSchristos #endif 262012573ebSchristos 263012573ebSchristos #ifndef ATTRIBUTE_RESULT_SIZE_2 264012573ebSchristos # if (GCC_VERSION >= 4003) 265012573ebSchristos # define ATTRIBUTE_RESULT_SIZE_2 __attribute__ ((alloc_size (2))) 266012573ebSchristos # else 267012573ebSchristos # define ATTRIBUTE_RESULT_SIZE_2 268012573ebSchristos #endif 269012573ebSchristos #endif 270012573ebSchristos 271012573ebSchristos #ifndef ATTRIBUTE_RESULT_SIZE_1_2 272012573ebSchristos # if (GCC_VERSION >= 4003) 273012573ebSchristos # define ATTRIBUTE_RESULT_SIZE_1_2 __attribute__ ((alloc_size (1, 2))) 274012573ebSchristos # else 275012573ebSchristos # define ATTRIBUTE_RESULT_SIZE_1_2 276012573ebSchristos #endif 277012573ebSchristos #endif 278012573ebSchristos 279012573ebSchristos /* Attribute `warn_unused_result' was valid as of gcc 3.3. */ 280012573ebSchristos #ifndef ATTRIBUTE_WARN_UNUSED_RESULT 281012573ebSchristos # if GCC_VERSION >= 3003 282012573ebSchristos # define ATTRIBUTE_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) 283012573ebSchristos # else 284012573ebSchristos # define ATTRIBUTE_WARN_UNUSED_RESULT 285012573ebSchristos # endif 286012573ebSchristos #endif 287012573ebSchristos 28875fd0b74Schristos /* We use __extension__ in some places to suppress -pedantic warnings 28975fd0b74Schristos about GCC extensions. This feature didn't work properly before 29075fd0b74Schristos gcc 2.8. */ 29175fd0b74Schristos #if GCC_VERSION < 2008 29275fd0b74Schristos #define __extension__ 29375fd0b74Schristos #endif 29475fd0b74Schristos 29575fd0b74Schristos /* This is used to declare a const variable which should be visible 29675fd0b74Schristos outside of the current compilation unit. Use it as 29775fd0b74Schristos EXPORTED_CONST int i = 1; 29875fd0b74Schristos This is because the semantics of const are different in C and C++. 29975fd0b74Schristos "extern const" is permitted in C but it looks strange, and gcc 30075fd0b74Schristos warns about it when -Wc++-compat is not used. */ 30175fd0b74Schristos #ifdef __cplusplus 30275fd0b74Schristos #define EXPORTED_CONST extern const 30375fd0b74Schristos #else 30475fd0b74Schristos #define EXPORTED_CONST const 30575fd0b74Schristos #endif 30675fd0b74Schristos 30775fd0b74Schristos /* Be conservative and only use enum bitfields with C++ or GCC. 30875fd0b74Schristos FIXME: provide a complete autoconf test for buggy enum bitfields. */ 30975fd0b74Schristos 31075fd0b74Schristos #ifdef __cplusplus 31175fd0b74Schristos #define ENUM_BITFIELD(TYPE) enum TYPE 31275fd0b74Schristos #elif (GCC_VERSION > 2000) 31375fd0b74Schristos #define ENUM_BITFIELD(TYPE) __extension__ enum TYPE 31475fd0b74Schristos #else 31575fd0b74Schristos #define ENUM_BITFIELD(TYPE) unsigned int 31675fd0b74Schristos #endif 31775fd0b74Schristos 318*e992f068Schristos #if defined(__cplusplus) && __cpp_constexpr >= 200704 319ede78133Schristos #define CONSTEXPR constexpr 32075fd0b74Schristos #else 321ede78133Schristos #define CONSTEXPR 32275fd0b74Schristos #endif 32375fd0b74Schristos 324ede78133Schristos /* A macro to disable the copy constructor and assignment operator. 325ede78133Schristos When building with C++11 and above, the methods are explicitly 326ede78133Schristos deleted, causing a compile-time error if something tries to copy. 327ede78133Schristos For C++03, this just declares the methods, causing a link-time 328ede78133Schristos error if the methods end up called (assuming you don't 329ede78133Schristos define them). For C++03, for best results, place the macro 330ede78133Schristos under the private: access specifier, like this, 331ede78133Schristos 332ede78133Schristos class name_lookup 333ede78133Schristos { 334ede78133Schristos private: 335ede78133Schristos DISABLE_COPY_AND_ASSIGN (name_lookup); 336ede78133Schristos }; 337ede78133Schristos 338ede78133Schristos so that most attempts at copy are caught at compile-time. */ 339ede78133Schristos 340*e992f068Schristos #if defined(__cplusplus) && __cplusplus >= 201103 341ede78133Schristos #define DISABLE_COPY_AND_ASSIGN(TYPE) \ 342ede78133Schristos TYPE (const TYPE&) = delete; \ 343ede78133Schristos void operator= (const TYPE &) = delete 344ede78133Schristos #else 345ede78133Schristos #define DISABLE_COPY_AND_ASSIGN(TYPE) \ 346ede78133Schristos TYPE (const TYPE&); \ 347ede78133Schristos void operator= (const TYPE &) 348ede78133Schristos #endif /* __cplusplus >= 201103 */ 349ede78133Schristos 35075fd0b74Schristos #ifdef __cplusplus 35175fd0b74Schristos } 35275fd0b74Schristos #endif 35375fd0b74Schristos 35475fd0b74Schristos #endif /* ansidecl.h */ 355