1 1.9 rillig /* $NetBSD: d_alignof.c,v 1.9 2023/06/30 09:21:52 rillig Exp $ */ 2 1.2 rillig # 3 "d_alignof.c" 3 1.2 rillig 4 1.3 rillig /* https://gcc.gnu.org/onlinedocs/gcc/Alignment.html */ 5 1.3 rillig 6 1.3 rillig unsigned long 7 1.3 rillig leading_and_trailing_alignof_type(void) 8 1.1 jruoho { 9 1.1 jruoho return __alignof__(short); 10 1.1 jruoho } 11 1.3 rillig 12 1.3 rillig unsigned long 13 1.3 rillig leading_alignof_type(void) 14 1.3 rillig { 15 1.3 rillig return __alignof(short); 16 1.3 rillig } 17 1.3 rillig 18 1.3 rillig unsigned long 19 1.3 rillig plain_alignof_type(void) 20 1.3 rillig { 21 1.3 rillig /* The plain word 'alignof' is not recognized by GCC. */ 22 1.4 rillig /* expect+2: error: function 'alignof' implicitly declared to return int [215] */ 23 1.4 rillig /* expect+1: error: syntax error 'short' [249] */ 24 1.3 rillig return alignof(short); 25 1.3 rillig } 26 1.8 rillig /* expect-1: warning: function 'plain_alignof_type' falls off bottom without returning value [217] */ 27 1.3 rillig 28 1.3 rillig unsigned long 29 1.3 rillig leading_and_trailing_alignof_expr(void) 30 1.3 rillig { 31 1.3 rillig return __alignof__ 3; 32 1.3 rillig } 33 1.3 rillig 34 1.3 rillig unsigned long 35 1.3 rillig leading_alignof_expr(void) 36 1.3 rillig { 37 1.3 rillig return __alignof 3; 38 1.3 rillig } 39 1.3 rillig 40 1.3 rillig unsigned long 41 1.3 rillig plain_alignof_expr(void) 42 1.3 rillig { 43 1.3 rillig /* The plain word 'alignof' is not recognized by GCC. */ 44 1.4 rillig /* expect+2: error: 'alignof' undefined [99] */ 45 1.3 rillig /* expect+1: error: syntax error '3' [249] */ 46 1.3 rillig return alignof 3; 47 1.3 rillig } 48 1.8 rillig /* expect-1: warning: function 'plain_alignof_expr' falls off bottom without returning value [217] */ 49 1.6 rillig 50 1.6 rillig 51 1.6 rillig /* 52 1.6 rillig * As with 'sizeof', the keyword '__alignof__' doesn't require parentheses 53 1.6 rillig * when followed by an expression. This allows for the seemingly strange 54 1.6 rillig * '->' after the parentheses, which in fact is perfectly fine. 55 1.6 rillig * 56 1.6 rillig * The NetBSD style guide says "We parenthesize sizeof expressions", even 57 1.6 rillig * though it is misleading in edge cases like this. The GCC manual says that 58 1.6 rillig * '__alignof__' and 'sizeof' are syntactically the same, therefore the same 59 1.6 rillig * reasoning applies to '__alignof__'. 60 1.6 rillig */ 61 1.6 rillig unsigned long 62 1.6 rillig alignof_pointer_to_member(void) 63 1.6 rillig { 64 1.6 rillig struct s { 65 1.6 rillig unsigned long member; 66 1.6 rillig } var = { 0 }, *ptr = &var; 67 1.6 rillig 68 1.6 rillig return __alignof__(ptr)->member + ptr->member; 69 1.6 rillig } 70 1.9 rillig 71 1.9 rillig void 72 1.9 rillig alignof_variants(void) 73 1.9 rillig { 74 1.9 rillig /* expect+1: error: negative array dimension (-4) [20] */ 75 1.9 rillig typedef int array_int[-(int)__alignof(int[3])]; 76 1.9 rillig 77 1.9 rillig /* expect+1: error: negative array dimension (-8) [20] */ 78 1.9 rillig typedef int array_double[-(int)__alignof(double[3])]; 79 1.9 rillig 80 1.9 rillig /* expect+1: error: cannot take size/alignment of function type 'function(int) returning int' [144] */ 81 1.9 rillig typedef int func[-(int)__alignof(int(int))]; 82 1.9 rillig 83 1.9 rillig struct int_double { 84 1.9 rillig int i; 85 1.9 rillig double d; 86 1.9 rillig }; 87 1.9 rillig /* expect+1: error: negative array dimension (-8) [20] */ 88 1.9 rillig typedef int struct_int_double[-(int)__alignof(struct int_double)]; 89 1.9 rillig 90 1.9 rillig struct chars { 91 1.9 rillig char name[20]; 92 1.9 rillig }; 93 1.9 rillig /* expect+1: error: negative array dimension (-1) [20] */ 94 1.9 rillig typedef int struct_chars[-(int)__alignof(struct chars)]; 95 1.9 rillig 96 1.9 rillig /* expect+1: warning: struct 'incomplete_struct' never defined [233] */ 97 1.9 rillig struct incomplete_struct; 98 1.9 rillig /* expect+1: error: cannot take size/alignment of incomplete type [143] */ 99 1.9 rillig typedef int incomplete_struct[-(int)__alignof(struct incomplete_struct)]; 100 1.9 rillig 101 1.9 rillig /* expect+1: warning: union 'incomplete_union' never defined [234] */ 102 1.9 rillig union incomplete_union; 103 1.9 rillig /* expect+1: error: cannot take size/alignment of incomplete type [143] */ 104 1.9 rillig typedef int incomplete_union[-(int)__alignof(union incomplete_union)]; 105 1.9 rillig 106 1.9 rillig /* expect+1: warning: enum 'incomplete_enum' never defined [235] */ 107 1.9 rillig enum incomplete_enum; 108 1.9 rillig /* expect+1: error: negative array dimension (-4) [20] */ 109 1.9 rillig typedef int incomplete_enum[-(int)__alignof(enum incomplete_enum)]; 110 1.9 rillig 111 1.9 rillig struct bit_fields { 112 1.9 rillig _Bool bit_field:1; 113 1.9 rillig }; 114 1.9 rillig /* 115 1.9 rillig * FIXME: This is not an attempt to initialize the typedef, it's the 116 1.9 rillig * initialization of a nested expression. 117 1.9 rillig */ 118 1.9 rillig /* expect+2: error: cannot initialize typedef '00000000_tmp' [25] */ 119 1.9 rillig /* expect+1: error: cannot take size/alignment of bit-field [145] */ 120 1.9 rillig typedef int bit_field[-(int)__alignof((struct bit_fields){0}.bit_field)]; 121 1.9 rillig 122 1.9 rillig /* expect+1: error: cannot take size/alignment of void [146] */ 123 1.9 rillig typedef int plain_void[-(int)__alignof(void)]; 124 1.9 rillig } 125