expr_sizeof.c revision 1.5 1 1.5 rillig /* $NetBSD: expr_sizeof.c,v 1.5 2023/03/28 14:44:34 rillig Exp $ */
2 1.1 rillig # 3 "expr_sizeof.c"
3 1.1 rillig
4 1.1 rillig /*
5 1.1 rillig * C99 6.5.3.4 "The sizeof operator"
6 1.1 rillig * C11 6.5.3.4 "The sizeof operator"
7 1.1 rillig */
8 1.1 rillig
9 1.5 rillig /* lint1-extra-flags: -X 351 */
10 1.5 rillig
11 1.1 rillig /*
12 1.1 rillig * A sizeof expression can either take a type name or an expression.
13 1.1 rillig */
14 1.1 rillig void sink(unsigned long);
15 1.1 rillig
16 1.1 rillig struct {
17 1.1 rillig int member;
18 1.1 rillig } s, *ps;
19 1.1 rillig
20 1.1 rillig /*
21 1.1 rillig * In a sizeof expression taking a type name, the type name must be enclosed
22 1.1 rillig * in parentheses.
23 1.1 rillig */
24 1.1 rillig /* expect+1: error: negative array dimension (-4) [20] */
25 1.1 rillig typedef int sizeof_int[-(int)sizeof(int)];
26 1.1 rillig
27 1.1 rillig /*
28 1.1 rillig * In a sizeof expression taking an expression, the expression may or may not
29 1.1 rillig * be enclosed in parentheses, like any other expression.
30 1.1 rillig */
31 1.1 rillig /* expect+1: error: negative array dimension (-4) [20] */
32 1.1 rillig typedef int sizeof_paren_zero[-(int)sizeof(0)];
33 1.1 rillig /* expect+1: error: negative array dimension (-4) [20] */
34 1.1 rillig typedef int sizeof_zero[-(int)sizeof 0];
35 1.1 rillig
36 1.1 rillig /*
37 1.1 rillig * Even though 's' is not a constant expression, 'sizeof s' is.
38 1.1 rillig */
39 1.1 rillig /* expect+1: error: negative array dimension (-4) [20] */
40 1.1 rillig typedef int sizeof_global_var[-(int)sizeof s];
41 1.1 rillig /* expect+1: error: negative array dimension (-4) [20] */
42 1.1 rillig typedef int sizeof_paren_global_var[-(int)sizeof(s)];
43 1.1 rillig
44 1.1 rillig /*
45 1.1 rillig * Even though 'sizeof(s)' may look like a function call expression, the
46 1.1 rillig * parentheses around 's' are ordinary parentheses and do not influence the
47 1.2 rillig * precedence.
48 1.2 rillig *
49 1.2 rillig * Therefore, the '.' following the '(s)' takes precedence over the 'sizeof'.
50 1.2 rillig * Same for the '->' following the '(ps)'. Same for the '[0]' following the
51 1.2 rillig * '(arr)'.
52 1.1 rillig */
53 1.1 rillig /* expect+1: error: negative array dimension (-4) [20] */
54 1.1 rillig typedef int sizeof_paren_global_struct_member[-(int)sizeof(s).member];
55 1.1 rillig /* expect+1: error: negative array dimension (-4) [20] */
56 1.1 rillig typedef int sizeof_paren_global_ptr_struct_member[-(int)sizeof(ps)->member];
57 1.2 rillig int arr[] = { 1, 2, 3 };
58 1.2 rillig /* expect+1: error: negative array dimension (-3) [20] */
59 1.2 rillig typedef int arr_count[-(int)sizeof(arr) / (int)sizeof(arr)[0]];
60 1.2 rillig
61 1.2 rillig /* FIXME: 'n' is actually used, for the variable length array. */
62 1.2 rillig /* expect+2: warning: argument 'n' unused in function 'variable_length_array' [231] */
63 1.2 rillig void
64 1.2 rillig variable_length_array(int n)
65 1.2 rillig {
66 1.2 rillig int local_arr[n + 5];
67 1.3 rillig
68 1.3 rillig /*
69 1.3 rillig * Since the array length is not constant, it cannot be used in a
70 1.4 rillig * typedef. Code like this is already rejected by the compiler. For
71 1.3 rillig * simplicity, lint assumes that the array has length 1.
72 1.3 rillig */
73 1.2 rillig /* expect+1: error: negative array dimension (-4) [20] */
74 1.2 rillig typedef int sizeof_local_arr[-(int)sizeof(local_arr)];
75 1.2 rillig }
76