]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/doc/gcc/extensions-to-the-c-language-family/referring-to-a-type-with-typeof.rst
13621410ff9d4c8439b869e793cfd13b0ac81d4f
[thirdparty/gcc.git] / gcc / doc / gcc / extensions-to-the-c-language-family / referring-to-a-type-with-typeof.rst
1 ..
2 Copyright 1988-2022 Free Software Foundation, Inc.
3 This is part of the GCC manual.
4 For copying conditions, see the copyright.rst file.
5
6 .. index:: typeof, sizeof, macros, types of arguments
7
8 .. _typeof:
9
10 Referring to a Type with typeof
11 *******************************
12
13 Another way to refer to the type of an expression is with ``typeof``.
14 The syntax of using of this keyword looks like ``sizeof``, but the
15 construct acts semantically like a type name defined with ``typedef``.
16
17 There are two ways of writing the argument to ``typeof`` : with an
18 expression or with a type. Here is an example with an expression:
19
20 .. code-block:: c++
21
22 typeof (x[0](1))
23
24 This assumes that ``x`` is an array of pointers to functions;
25 the type described is that of the values of the functions.
26
27 Here is an example with a typename as the argument:
28
29 .. code-block:: c++
30
31 typeof (int *)
32
33 Here the type described is that of pointers to ``int``.
34
35 If you are writing a header file that must work when included in ISO C
36 programs, write ``__typeof__`` instead of ``typeof``.
37 See :ref:`alternate-keywords`.
38
39 A ``typeof`` construct can be used anywhere a typedef name can be
40 used. For example, you can use it in a declaration, in a cast, or inside
41 of ``sizeof`` or ``typeof``.
42
43 The operand of ``typeof`` is evaluated for its side effects if and
44 only if it is an expression of variably modified type or the name of
45 such a type.
46
47 ``typeof`` is often useful in conjunction with
48 statement expressions (see :ref:`statement-exprs`).
49 Here is how the two together can
50 be used to define a safe 'maximum' macro which operates on any
51 arithmetic type and evaluates each of its arguments exactly once:
52
53 .. code-block:: c++
54
55 #define max(a,b) \
56 ({ typeof (a) _a = (a); \
57 typeof (b) _b = (b); \
58 _a > _b ? _a : _b; })
59
60 .. index:: underscores in variables in macros, _ in variables in macros, local variables in macros, variables, local, in macros, macros, local variables in
61
62 The reason for using names that start with underscores for the local
63 variables is to avoid conflicts with variable names that occur within the
64 expressions that are substituted for ``a`` and ``b``. Eventually we
65 hope to design a new form of declaration syntax that allows you to declare
66 variables whose scopes start only after their initializers; this will be a
67 more reliable way to prevent such conflicts.
68
69 Some more examples of the use of ``typeof`` :
70
71 * This declares ``y`` with the type of what ``x`` points to.
72
73 .. code-block:: c++
74
75 typeof (*x) y;
76
77 * This declares ``y`` as an array of such values.
78
79 .. code-block:: c++
80
81 typeof (*x) y[4];
82
83 * This declares ``y`` as an array of pointers to characters:
84
85 .. code-block:: c++
86
87 typeof (typeof (char *)[4]) y;
88
89 It is equivalent to the following traditional C declaration:
90
91 .. code-block:: c++
92
93 char *y[4];
94
95 To see the meaning of the declaration using ``typeof``, and why it
96 might be a useful way to write, rewrite it with these macros:
97
98 .. code-block:: c++
99
100 #define pointer(T) typeof(T *)
101 #define array(T, N) typeof(T [N])
102
103 Now the declaration can be rewritten this way:
104
105 .. code-block:: c++
106
107 array (pointer (char), 4) y;
108
109 Thus, ``array (pointer (char), 4)`` is the type of arrays of 4
110 pointers to ``char``.
111
112 In GNU C, but not GNU C++, you may also declare the type of a variable
113 as ``__auto_type``. In that case, the declaration must declare
114 only one variable, whose declarator must just be an identifier, the
115 declaration must be initialized, and the type of the variable is
116 determined by the initializer; the name of the variable is not in
117 scope until after the initializer. (In C++, you should use C++11
118 ``auto`` for this purpose.) Using ``__auto_type``, the
119 'maximum' macro above could be written as:
120
121 .. code-block:: c++
122
123 #define max(a,b) \
124 ({ __auto_type _a = (a); \
125 __auto_type _b = (b); \
126 _a > _b ? _a : _b; })
127
128 Using ``__auto_type`` instead of ``typeof`` has two advantages:
129
130 * Each argument to the macro appears only once in the expansion of
131 the macro. This prevents the size of the macro expansion growing
132 exponentially when calls to such macros are nested inside arguments of
133 such macros.
134
135 * If the argument to the macro has variably modified type, it is
136 evaluated only once when using ``__auto_type``, but twice if
137 ``typeof`` is used.