History

Implement C99 Variable Length Arrays

Implement C99 Variable Length Arrays in tinycc: - Support VLA with multiple level (nested vla) - Update documentation with regards to VT_VLA - Add a testsuite in tcctest.c

Thomas Preud'homme committed 15 years ago

Commit a5a50ea1 parent d35a3ac6 files · +169 −33Browse files

Unified · Split

6 files
  1. Changelog +1 −0
  2. TODO +0 −1
  3. tcc-doc.texi +14 −2
  4. tcc.h +2 −0
  5. tccgen.c +130 −30
  6. tests/tcctest.c +22 −0
Changelog+1−0
@@ -12,6 +12,7 @@ not released: · 11 unmodified lines
12- fix 32 to 64 bit casts, alignment and struct issues (Shinichiro Hamaji)12- fix 32 to 64 bit casts, alignment and struct issues (Shinichiro Hamaji)
13- mimic all GNU -option forms supported by ld (Kirill Smelkov)13- mimic all GNU -option forms supported by ld (Kirill Smelkov)
14- support indirect functions as externals (Thomas Preud'homme)14- support indirect functions as externals (Thomas Preud'homme)
15- Add support for C99 variable length arrays (Thomas Preud'homme)
15 16
16version 0.9.25:17version 0.9.25:
17 18
TODO+0−1
@@ -48,7 +48,6 @@ Missing features: · 47 unmodified lines
48- improve '-E' option.48- improve '-E' option.
49- atexit (Nigel Horne)49- atexit (Nigel Horne)
50- packed attribute50- packed attribute
51- C99: add variable size arrays (gcc 3.2 testsuite issue)
52- C99: add complex types (gcc 3.2 testsuite issue)51- C99: add complex types (gcc 3.2 testsuite issue)
53- postfix compound literals (see 20010124-1.c)52- postfix compound literals (see 20010124-1.c)
54 53
tcc-doc.texi+14−2
@@ -929,7 +929,11 @@ be the best solution. · 928 unmodified lines
929#define VT_BTYPE 0x000f /* mask for basic type */929#define VT_BTYPE 0x000f /* mask for basic type */
930#define VT_UNSIGNED 0x0010 /* unsigned type */930#define VT_UNSIGNED 0x0010 /* unsigned type */
931#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */931#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
932#define VT_VLA 0x10000 /* VLA type (also has VT_PTR and VT_ARRAY) */
932#define VT_BITFIELD 0x0040 /* bitfield modifier */933#define VT_BITFIELD 0x0040 /* bitfield modifier */
934#define VT_CONSTANT 0x0800 /* const modifier */
935#define VT_VOLATILE 0x1000 /* volatile modifier */
936#define VT_SIGNED 0x2000 /* signed type */
933 937
934#define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */938#define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
935@end example939@end example
@@ -942,7 +946,8 @@ The @code{VT_UNSIGNED} flag can be set for chars, shorts, ints and long · 6 unmodified lines
942longs.946longs.
943 947
944Arrays are considered as pointers @code{VT_PTR} with the flag948Arrays are considered as pointers @code{VT_PTR} with the flag
945@code{VT_ARRAY} set.949@code{VT_ARRAY} set. Variable length arrays are considered as special
950arrays and therefore also have flag @code{VT_VLA} set.
946 951
947The @code{VT_BITFIELD} flag can be set for chars, shorts, ints and long952The @code{VT_BITFIELD} flag can be set for chars, shorts, ints and long
948longs. If it is set, then the bitfield position is stored from bits953longs. If it is set, then the bitfield position is stored from bits
@@ -958,6 +963,10 @@ integer: · 9 unmodified lines
958#define VT_EXTERN 0x00000080 /* extern definition */963#define VT_EXTERN 0x00000080 /* extern definition */
959#define VT_STATIC 0x00000100 /* static variable */964#define VT_STATIC 0x00000100 /* static variable */
960#define VT_TYPEDEF 0x00000200 /* typedef definition */965#define VT_TYPEDEF 0x00000200 /* typedef definition */
966#define VT_INLINE 0x00000400 /* inline definition */
967#define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */
968#define VT_EXPORT 0x00008000 /* win32: data exported from dll */
969#define VT_WEAK 0x00010000 /* win32: data exported from dll */
961@end example970@end example
962 971
963@section Symbols972@section Symbols
@@ -969,7 +978,10 @@ contains @code{Sym} structures. · 5 unmodified lines
969an idenfier is also a token, so a string is never necessary to store978an idenfier is also a token, so a string is never necessary to store
970it). @code{Sym.t} gives the type of the symbol. @code{Sym.r} is usually979it). @code{Sym.t} gives the type of the symbol. @code{Sym.r} is usually
971the register in which the corresponding variable is stored. @code{Sym.c} is980the register in which the corresponding variable is stored. @code{Sym.c} is
972usually a constant associated to the symbol.981usually a constant associated to the symbol like its address for normal
982symbols, and the number of entries for symbols representing arrays.
983Variable length arrays use @code{Sym.r} instead, which is a pointer to
984a @code{SValue} holding its runtime size.
973 985
974Four main symbol stacks are defined:986Four main symbol stacks are defined:
975 987
tcc.h+2−0
@@ -224,6 +224,7 @@ typedef struct Sym { · 223 unmodified lines
224 union {224 union {
225 long c; /* associated number */225 long c; /* associated number */
226 int *d; /* define token stream */226 int *d; /* define token stream */
227 SValue *s; /* associated stack value */
227 };228 };
228 CType type; /* associated type */229 CType type; /* associated type */
229 union {230 union {
@@ -616,6 +617,7 @@ struct TCCState { · 386 unmodified lines
616#define VT_BTYPE 0x000f /* mask for basic type */617#define VT_BTYPE 0x000f /* mask for basic type */
617#define VT_UNSIGNED 0x0010 /* unsigned type */618#define VT_UNSIGNED 0x0010 /* unsigned type */
618#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */619#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
620#define VT_VLA 0x10000 /* VLA type (also has VT_PTR and VT_ARRAY) */
619#define VT_BITFIELD 0x0040 /* bitfield modifier */621#define VT_BITFIELD 0x0040 /* bitfield modifier */
620#define VT_CONSTANT 0x0800 /* const modifier */622#define VT_CONSTANT 0x0800 /* const modifier */
621#define VT_VOLATILE 0x1000 /* volatile modifier */623#define VT_VOLATILE 0x1000 /* volatile modifier */
tccgen.c+130−30
@@ -78,6 +78,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_re · 77 unmodified lines
78static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);78static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
79static void expr_eq(void);79static void expr_eq(void);
80static void unary_type(CType *type);80static void unary_type(CType *type);
81static void vla_runtime_type_size(CType *type, int *a);
81static int is_compatible_parameter_types(CType *type1, CType *type2);82static int is_compatible_parameter_types(CType *type1, CType *type2);
82static void expr_type(CType *type);83static void expr_type(CType *type);
83 84
@@ -1455,6 +1456,12 @@ static int pointed_size(CType *type) · 1371 unmodified lines
1455 return type_size(pointed_type(type), &align);1456 return type_size(pointed_type(type), &align);
1456}1457}
1457 1458
1459static void vla_runtime_pointed_size(CType *type)
1460{
1461 int align;
1462 vla_runtime_type_size(pointed_type(type), &align);
1463}
1464
1458static inline int is_null_pointer(SValue *p)1465static inline int is_null_pointer(SValue *p)
1459{1466{
1460 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)1467 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
@@ -1543,11 +1550,20 @@ ST_FUNC void gen_op(int op) · 82 unmodified lines
1543 }1550 }
1544 /* if both pointers, then it must be the '-' op */1551 /* if both pointers, then it must be the '-' op */
1545 if (bt1 == VT_PTR && bt2 == VT_PTR) {1552 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1553 int ptr1_is_vla;
1554
1555 ptr1_is_vla = 0;
1546 if (op != '-')1556 if (op != '-')
1547 error("cannot use pointers here");1557 error("cannot use pointers here");
1548 check_comparison_pointer_types(vtop - 1, vtop, op);1558 check_comparison_pointer_types(vtop - 1, vtop, op);
1549 /* XXX: check that types are compatible */1559 /* XXX: check that types are compatible */
1550 u = pointed_size(&vtop[-1].type);1560 if (vtop[-1].type.t & VT_VLA) {
1561 vla_runtime_pointed_size(&vtop[-1].type);
1562 vrott(3);
1563 ptr1_is_vla = 1;
1564 } else {
1565 u = pointed_size(&vtop[-1].type);
1566 }
1551 gen_opic(op);1567 gen_opic(op);
1552 /* set to integer type */1568 /* set to integer type */
1553#ifdef TCC_TARGET_X86_641569#ifdef TCC_TARGET_X86_64
@@ -1555,7 +1571,10 @@ ST_FUNC void gen_op(int op) · 1 unmodified line
1555#else1571#else
1556 vtop->type.t = VT_INT; 1572 vtop->type.t = VT_INT;
1557#endif1573#endif
1558 vpushi(u);1574 if (ptr1_is_vla)
1575 vswap();
1576 else
1577 vpushi(u);
1559 gen_op(TOK_PDIV);1578 gen_op(TOK_PDIV);
1560 } else {1579 } else {
1561 /* exactly one pointer : must be '+' or '-'. */1580 /* exactly one pointer : must be '+' or '-'. */
@@ -1567,16 +1586,20 @@ ST_FUNC void gen_op(int op) · 5 unmodified lines
1567 swap(&t1, &t2);1586 swap(&t1, &t2);
1568 }1587 }
1569 type1 = vtop[-1].type;1588 type1 = vtop[-1].type;
1570 type1.t &= ~VT_ARRAY;1589 type1.t &= ~(VT_ARRAY|VT_VLA);
1571 u = pointed_size(&vtop[-1].type);1590 if (vtop[-1].type.t & VT_VLA)
1572 if (u < 0)1591 vla_runtime_pointed_size(&vtop[-1].type);
1573 error("unknown array element size");1592 else {
1593 u = pointed_size(&vtop[-1].type);
1594 if (u < 0)
1595 error("unknown array element size");
1574#ifdef TCC_TARGET_X86_641596#ifdef TCC_TARGET_X86_64
1575 vpushll(u);1597 vpushll(u);
1576#else1598#else
1577 /* XXX: cast to int ? (long long case) */1599 /* XXX: cast to int ? (long long case) */
1578 vpushi(u);1600 vpushi(u);
1579#endif1601#endif
1602 }
1580 gen_op('*');1603 gen_op('*');
1581#ifdef CONFIG_TCC_BCHECK1604#ifdef CONFIG_TCC_BCHECK
1582 /* if evaluating constant expression, no code should be1605 /* if evaluating constant expression, no code should be
@@ -1932,7 +1955,7 @@ static void gen_cast(CType *type) · 349 unmodified lines
1932 vtop->type = *type;1955 vtop->type = *type;
1933}1956}
1934 1957
1935/* return type size. Put alignment at 'a' */1958/* return type size as known at compile time. Put alignment at 'a' */
1936ST_FUNC int type_size(CType *type, int *a)1959ST_FUNC int type_size(CType *type, int *a)
1937{1960{
1938 Sym *s;1961 Sym *s;
@@ -1945,7 +1968,10 @@ ST_FUNC int type_size(CType *type, int *a) · 6 unmodified lines
1945 *a = s->r;1968 *a = s->r;
1946 return s->c;1969 return s->c;
1947 } else if (bt == VT_PTR) {1970 } else if (bt == VT_PTR) {
1948 if (type->t & VT_ARRAY) {1971 if (type->t & VT_VLA) {
1972 *a = 1;
1973 return 0;
1974 } else if (type->t & VT_ARRAY) {
1949 int ts;1975 int ts;
1950 1976
1951 s = type->ref;1977 s = type->ref;
@@ -1992,6 +2018,30 @@ ST_FUNC int type_size(CType *type, int *a) · 40 unmodified lines
1992 }2018 }
1993}2019}
1994 2020
2021/* push type size as known at runtime time on top of value stack. Put
2022 alignment at 'a' */
2023ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2024{
2025 if (type->t & VT_VLA) {
2026 Sym *s;
2027
2028 s = type->ref;
2029 vla_runtime_type_size(&s->type, a);
2030 vpushv(s->s);
2031 if ((vtop->r & (VT_SYM|VT_LVAL|VT_VALMASK)) != VT_CONST) {
2032 gv_dup();
2033 vswap();
2034 vpop();
2035 }
2036 gen_op('*');
2037 } else {
2038 int size;
2039
2040 size = type_size(type, a);
2041 vpushi(size);
2042 }
2043}
2044
1995/* return the pointed type of t */2045/* return the pointed type of t */
1996static inline CType *pointed_type(CType *type)2046static inline CType *pointed_type(CType *type)
1997{2047{
@@ -3103,25 +3153,43 @@ static void post_type(CType *type, AttributeDef *ad) · 1105 unmodified lines
3103 type->t = t1 | VT_FUNC;3153 type->t = t1 | VT_FUNC;
3104 type->ref = s;3154 type->ref = s;
3105 } else if (tok == '[') {3155 } else if (tok == '[') {
3156 SValue *last_vtop = NULL;
3157
3106 /* array definition */3158 /* array definition */
3107 next();3159 next();
3108 if (tok == TOK_RESTRICT1)3160 if (tok == TOK_RESTRICT1)
3109 next();3161 next();
3110 n = -1;3162 n = -1;
3111 if (tok != ']') {3163 if (tok != ']') {
3112 n = expr_const();3164 gexpr();
3113 if (n < 0)3165 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3114 error("invalid array size"); 3166 n = vtop->c.i;
3167 last_vtop = vtop;
3168 if (n < 0)
3169 error("invalid array size");
3170 } else {
3171 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3172 error("size of variable length array should be an integer");
3173 type->t |= VT_VLA;
3174 last_vtop = vtop;
3175 }
3115 }3176 }
3116 skip(']');3177 skip(']');
3117 /* parse next post type */3178 /* parse next post type */
3118 t1 = type->t & VT_STORAGE;3179 t1 = type->t & (VT_STORAGE|VT_VLA);
3119 type->t &= ~VT_STORAGE;3180 type->t &= ~(VT_STORAGE|VT_VLA);
3120 post_type(type, ad);3181 post_type(type, ad);
3182 t1 |= type->t & VT_VLA;
3121 3183
3122 /* we push a anonymous symbol which will contain the array3184 /* we push an anonymous symbol which will contain the array
3123 element type */3185 element type */
3124 s = sym_push(SYM_FIELD, type, 0, n);3186 s = sym_push(SYM_FIELD, type, 0, n);
3187 if (t1 & VT_VLA) {
3188 s->s = last_vtop; // That's ok, we don't need n with VLA
3189 } else {
3190 if (n >= 0)
3191 vpop();
3192 }
3125 type->t = t1 | VT_ARRAY | VT_PTR;3193 type->t = t1 | VT_ARRAY | VT_PTR;
3126 type->ref = s;3194 type->ref = s;
3127 }3195 }
@@ -3490,11 +3558,18 @@ ST_FUNC void unary(void) · 362 unmodified lines
3490 next();3558 next();
3491 in_sizeof++;3559 in_sizeof++;
3492 unary_type(&type); // Perform a in_sizeof = 0;3560 unary_type(&type); // Perform a in_sizeof = 0;
3493 size = type_size(&type, &align);3561 if ((t == TOK_SIZEOF) && (type.t & VT_VLA)) {
3562 vla_runtime_type_size(&type, &align);
3563 size = 0;
3564 } else {
3565 size = type_size(&type, &align);
3566 }
3494 if (t == TOK_SIZEOF) {3567 if (t == TOK_SIZEOF) {
3495 if (size < 0)3568 if (!(type.t & VT_VLA)) {
3496 error("sizeof applied to an incomplete type");3569 if (size < 0)
3497 vpushi(size);3570 error("sizeof applied to an incomplete type");
3571 vpushi(size);
3572 }
3498 } else {3573 } else {
3499 vpushi(align);3574 vpushi(align);
3500 }3575 }
@@ -3653,7 +3728,10 @@ ST_FUNC void unary(void) · 152 unmodified lines
3653 } else {3728 } else {
3654 r = s->r;3729 r = s->r;
3655 }3730 }
3656 vset(&s->type, r, s->c);3731 if (s->type.t & VT_VLA)
3732 vpushv(s->s);
3733 else
3734 vset(&s->type, r, s->c);
3657 /* if forward reference, we must point to s */3735 /* if forward reference, we must point to s */
3658 if (vtop->r & VT_SYM) {3736 if (vtop->r & VT_SYM) {
3659 vtop->sym = s;3737 vtop->sym = s;
@@ -4782,7 +4860,18 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 1122 unmodified lines
4782 Sym *s, *f;4860 Sym *s, *f;
4783 CType *t1;4861 CType *t1;
4784 4862
4785 if (type->t & VT_ARRAY) {4863 if (type->t & VT_VLA) {
4864 int a;
4865 CValue retcval;
4866
4867 vpush_global_sym(&func_old_type, TOK_alloca);
4868 vla_runtime_type_size(type, &a);
4869 gfunc_call(1);
4870
4871 /* return value */
4872 retcval.i = 0;
4873 vsetc(type, REG_IRET, &retcval);
4874 } else if (type->t & VT_ARRAY) {
4786 s = type->ref;4875 s = type->ref;
4787 n = s->c;4876 n = s->c;
4788 array_length = 0;4877 array_length = 0;
@@ -5013,6 +5102,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 224 unmodified lines
5013 ParseState saved_parse_state = {0};5102 ParseState saved_parse_state = {0};
5014 TokenString init_str;5103 TokenString init_str;
5015 Section *sec;5104 Section *sec;
5105 Sym *vla = NULL;
5016 5106
5017 size = type_size(type, &align);5107 size = type_size(type, &align);
5018 /* If unknown size, we must evaluate it before5108 /* If unknown size, we must evaluate it before
@@ -5078,8 +5168,12 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 59 unmodified lines
5078 if ((r & VT_VALMASK) == VT_LOCAL) {5168 if ((r & VT_VALMASK) == VT_LOCAL) {
5079 sec = NULL;5169 sec = NULL;
5080#ifdef CONFIG_TCC_BCHECK5170#ifdef CONFIG_TCC_BCHECK
5081 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))5171 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5082 loc--;5172 if (type->t & VT_VLA)
5173 warning("Array bound check don't work for VLA");
5174 else
5175 loc--;
5176 }
5083#endif5177#endif
5084 loc = (loc - size) & -align;5178 loc = (loc - size) & -align;
5085 addr = loc;5179 addr = loc;
@@ -5087,7 +5181,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 1 unmodified line
5087 /* handles bounds */5181 /* handles bounds */
5088 /* XXX: currently, since we do only one pass, we cannot track5182 /* XXX: currently, since we do only one pass, we cannot track
5089 '&' operators, so we add only arrays */5183 '&' operators, so we add only arrays */
5090 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {5184 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY) &&
5185 !(type->t & VT_VLA)) {
5091 unsigned long *bounds_ptr;5186 unsigned long *bounds_ptr;
5092 /* add padding between regions */5187 /* add padding between regions */
5093 loc--;5188 loc--;
@@ -5099,7 +5194,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 5 unmodified lines
5099#endif5194#endif
5100 if (v) {5195 if (v) {
5101 /* local variable */5196 /* local variable */
5102 sym_push(v, type, r, addr);5197 vla = sym_push(v, type, r, addr);
5103 } else {5198 } else {
5104 /* push local reference */5199 /* push local reference */
5105 vset(type, r, addr);5200 vset(type, r, addr);
@@ -5214,8 +5309,10 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 108 unmodified lines
5214 }5309 }
5215#endif5310#endif
5216 }5311 }
5217 if (has_init) {5312 if (has_init || (type->t & VT_VLA)) {
5218 decl_initializer(type, sec, addr, 1, 0);5313 decl_initializer(type, sec, addr, 1, 0);
5314 if (type->t & VT_VLA)
5315 vla->s = vtop;
5219 /* restore parse state if needed */5316 /* restore parse state if needed */
5220 if (init_str.str) {5317 if (init_str.str) {
5221 tok_str_free(init_str.str);5318 tok_str_free(init_str.str);
@@ -5584,9 +5681,12 @@ ST_FUNC void decl(int l) · 362 unmodified lines
5584 if (!(type.t & VT_ARRAY))5681 if (!(type.t & VT_ARRAY))
5585 r |= lvalue_type(type.t);5682 r |= lvalue_type(type.t);
5586 has_init = (tok == '=');5683 has_init = (tok == '=');
5684 if (has_init && (type.t & VT_VLA))
5685 error("Variable length array cannot be initialized");
5587 if ((btype.t & VT_EXTERN) ||5686 if ((btype.t & VT_EXTERN) ||
5588 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&5687 ((type.t & VT_ARRAY) && (!(type.t & VT_VLA)) &&
5589 !has_init && l == VT_CONST && type.ref->c < 0)) {5688 (type.t & VT_STATIC) && !has_init && l == VT_CONST &&
5689 type.ref->c < 0)) {
5590 /* external variable */5690 /* external variable */
5591 /* NOTE: as GCC, uninitialized global static5691 /* NOTE: as GCC, uninitialized global static
5592 arrays of null size are considered as5692 arrays of null size are considered as
tests/tcctest.c+22−0
@@ -77,6 +77,7 @@ void whitespace_test(void); · 76 unmodified lines
77void relocation_test(void);77void relocation_test(void);
78void old_style_function(void);78void old_style_function(void);
79void alloca_test(void);79void alloca_test(void);
80void c99_vla_test(int size1, int size2);
80void sizeof_test(void);81void sizeof_test(void);
81void typeof_test(void);82void typeof_test(void);
82void local_label_test(void);83void local_label_test(void);
@@ -563,6 +564,7 @@ int main(int argc, char **argv) · 480 unmodified lines
563 relocation_test();564 relocation_test();
564 old_style_function();565 old_style_function();
565 alloca_test();566 alloca_test();
567 c99_vla_test(5, 2);
566 sizeof_test();568 sizeof_test();
567 typeof_test();569 typeof_test();
568 statement_expr_test();570 statement_expr_test();
@@ -2018,6 +2020,26 @@ void alloca_test() · 1449 unmodified lines
2018#endif2020#endif
2019}2021}
2020 2022
2023void c99_vla_test(int size1, int size2)
2024{
2025#if defined __i386__ || defined __x86_64__
2026 int tab1[size1 * size2][2], tab2[10][2];
2027 void *tab1_ptr, *tab2_ptr;
2028
2029 printf("Test C99 VLA 1 (sizeof): ");
2030 printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
2031 tab1_ptr = tab1;
2032 tab2_ptr = tab2;
2033 printf("Test C99 VLA 2 (ptrs substract): ");
2034 printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED");
2035 printf("Test C99 VLA 3 (ptr add): ");
2036 printf("%s\n", &tab1[5][1] == (tab1_ptr + (5 * 2 + 1) * sizeof(int)) ? "PASSED" : "FAILED");
2037 printf("Test C99 VLA 4 (ptr access): ");
2038 tab1[size1][1] = 42;
2039 printf("%s\n", (*((int *) (tab1_ptr + (size1 * 2 + 1) * sizeof(int))) == 42) ? "PASSED" : "FAILED");
2040#endif
2041}
2042
2021void sizeof_test(void)2043void sizeof_test(void)
2022{2044{
2023 int a;2045 int a;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t