Search code examples
cgcccastingunsignedtypeof

Why doesn't unsigned typeof(var) work? const typeof(x) works fine, so why not?


In a macro I would want to make the value the same width, however unsigned. So, a natural unsigned typeof(x) came to mind. However, it doesn't compile:

/home/guest/mc.c: In function ‘main’:
/home/guest/mc.c:14:36: error: expected ‘)’ before ‘typeof’
   14 |                         *((unsigned typeof(minus)*)&minus));

I wonder why it is so? Maybe I'm doing something wrong? Can I somehow add unsigned to the type of a variable?

PS. I've noted, that similar cast adding const works OK:

#define add_const(x) ((const typeof(x))(x))

Also, adding * to create a pointer type also works OK.


Solution

  • The fundamental reason why unsigned typeof(x) doesn't work but const typeof(x) does is that unsigned and const are two different syntax components. unsigned it a type specifier, while const is a type qualifier.

    The list of type specifiers (note that a bare unsigned is syntactically equivalent to unsigned int:

    6.7.2 Type specifiers

    1. Syntax

          type-specifier:
                 void
                 char
                 short
                 int
                 long
                 float
                 double
                 signed
                 unsigned
                 _Bool
                 _Complex
                 atomic-type-specifier
                 struct-or-union-specifier
                 enum-specifier
                 typedef-name
    

    2. Constraints

    ...

    • unsigned, or unsigned int

    So unsigned typeof(x) is the equivalent of unsigned int typeof(x).

    const is a type qualifier:

    6.7.3 Type qualifiers

    1. Syntax

          type-qualifier:
                 const
                 restrict
                 volatile
                 _Atomic
    

    const char is proper C code, assuming x is a char. unsigned int char is not proper C code.