Using constants and their associated modifiers using gcc

前端 未结 3 442
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-24 00:01

I was not sure what to call these flags, but what I am referring to is:

#define TEST_DEF 50000U //<- the \"U\" here

Google searching when yo

相关标签:
3条回答
  • 2021-01-24 00:24

    For integers, the section of the standard (ISO/IEC 9899:2011 — aka C2011 or C11) defining these suffixes is:

    §6.4.4.1 Integer constants

    Where it defines the integer-suffixes:

    integer-suffix:
        unsigned-suffix long-suffixopt
        unsigned-suffix long-long-suffix
        long-suffix unsigned-suffixopt
        long-long-suffix unsigned-suffixopt

    unsigned-suffix: one of
        u U

    long-suffix: one of
        l L

    long-long-suffix: one of
        ll LL

    The corresponding suffixes for floating point numbers are f, F, l and L (for float and long double).

    Note that it would be perverse to use l because it is far too easily confused with 1, so the qualifiers are most often written with upper-case letters.

    If you want to create integer literals that are of a given size, then the facilities to do so are standardized by <stdint.h> (added in C99).

    The header (conditionally) defines fixed-size types such as int8_t and uint16_t. It also (unconditionally) provides minimum-sized types such as int_least8_t and uint_least16_t. If it cannot provide exact types (perhaps because the word size is 36 bits, so sizes 9, 18 and 36 are handled), it can still provide the least types.

    It also provide macros such as INT8_C which ensure that the argument is an int_least8_t value.

    Hence, you could use:

    #include <stdint.h>
    
    #define TEST_DEF UINT16_C(50000)
    

    and you are guaranteed that the value will be at least 16 bits of unsigned integer, and formatted/qualified correctly.

    §7.20.4 Macros for integer constants

    ¶1 The following function-like macros expand to integer constants suitable for initializing objects that have integer types corresponding to types defined in <stdint.h>. Each macro name corresponds to a similar type name in 7.20.1.2 or 7.20.1.5.

    ¶2 The argument in any instance of these macros shall be an unsuffixed integer constant (as defined in 6.4.4.1) with a value that does not exceed the limits for the corresponding type.

    ¶3 Each invocation of one of these macros shall expand to an integer constant expression suitable for use in #if preprocessing directives. The type of the expression shall have the same type as would an expression of the corresponding type converted according to the integer promotions. The value of the expression shall be that of the argument.

    7.20.4.1 Macros for minimum-width integer constants

    ¶1 The macro INTN_C(value) shall expand to an integer constant expression corresponding to the type int_leastN_t. The macro UINTN_C(value) shall expand to an integer constant expression corresponding to the type uint_leastN_t. For example, if uint_least64_t is a name for the type unsigned long long int, then UINT64_C(0x123) might expand to the integer constant 0x123ULL.

    0 讨论(0)
  • 2021-01-24 00:39

    This is an unsigned literal (U is suffix). See: http://en.cppreference.com/w/cpp/language/integer_literal

    0 讨论(0)
  • 2021-01-24 00:46

    There are five integer literal suffixes in C: u, l, ul, ll, and ull. Unlike nearly everything else in C they are case insensitive; also, ul and ull can be written as lu and llu respectively (however, lul is not acceptable).

    They control the type of the constant. They work approximately like this:

    literal │ type
    ────────┼───────────────────────
    500     │ int
    500u    │ unsigned int
    500l    │ long int
    500ul   │ unsigned long int
    500ll   │ long long int
    500ull  │ unsigned long long int
    

    This is only an approximation, because if the constant is too large for the indicated type, it is "promoted" to a larger type. The rules for this are sufficiently complicated that I'm not going to try to describe them. The rules for "promoting" hexadecimal and octal literals are slightly different than the rules for "promoting" decimal literals, and they are also slightly different in C99 versus C90 and different again in C++.

    Because of the promotion effect, is not possible to use these suffixes to limit constants to any size. If you write 281474976710656 on a system where int and long are both 32 bits wide, the constant will be given type long long even though you didn't say to do that. Moreover, there are no suffixes to force a constant to have type short nor char. You can indicate your intent with the [U]INT{8,16,32,64,MAX}_C macros from <stdint.h>, but those do not impose any upper limit either, and on all systems I can conveniently get at right now (OSX, Linux), *INT8_C and *INT16_C actually produce values with type (unsigned) int.

    Your compiler may, but is not required to, warn if you write ((uint8_t) 512) or similar (where 512 is a compile-time constant value outside the range of the type. In C11 you can use static_assert (from <assert.h>) to force the issue but it might be a bit tedious to write.

    0 讨论(0)
提交回复
热议问题