Op 31-07-2025 om 09:39 schreef Freelance Roemke:
Hi,
I just tried to compile a 35 year old code (not from me) that looks
similar to
cat <<-KWC > kw.c
#include <stdio.h>
typedef char *keywords[];
extern keywords ord2kw;
extern keywords ord3kw;
keywords ord2kw= {
"E", "L", NULL
};
keywords ord3kw= {
"D", "T", "I",
"D2", "T2", "I2", "P",
"P2", "V", NULL
};
int main()
{
printf("%u\n",sizeof ord2kw);
printf("%u\n",sizeof ord3kw);
}
KWC
and while all the gcc and clang version since then have compiled it
and also used a different size for ord2kw and ord3kw, tcc now tells me
kw.c:16: error: too many initializers
and only if both ord2kw and ord3kw have the same number of elements,
the error message disappears.
Could anyone enlighten me the reason for that, maybe with a reference
to the C89 or C99 standard?
As far as I read the C99 standard, e.g., it says
/6.7.8 22 If an array of unknown size is initialized, its size is
determined by the largest indexed
element with an explicit initializer. At the end of its initializer
list, the *array* no longer
has incomplete type.
/
but IMHO this does not mean that the *type* (here keywords) no longer
has an incomplete type.
And is there an option to change that behaviour?
I think I found the problem. The typedef type was used twice.
The first time ord2kw set the type to size 3.
Then ord3kw overflowed because the size was now 3.
(It also works when you remove the 2 extern lines)
So I unshared the type with attached patch.
I am not sure I did this at the rigth place but it works
for the testsuite and some other code.
Herman
diff --git a/tccgen.c b/tccgen.c
index c25a224..d142e74 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -8211,13 +8211,21 @@ static void decl_initializer_alloc(CType *type,
AttributeDef *ad, int r,
/* see if the symbol was already defined */
sym = sym_find(v);
if (sym) {
- if (p.flex_array_ref && (sym->type.t & type->t & VT_ARRAY)
- && sym->type.ref->c > type->ref->c) {
- /* flex array was already declared with explicit size
- extern int arr[10];
- int arr[] = { 1,2,3 }; */
- type->ref->c = sym->type.ref->c;
- size = type_size(type, &align);
+ if (p.flex_array_ref && (sym->type.t & type->t & VT_ARRAY)) {
+ if (sym->type.ref->c > type->ref->c) {
+ /* flex array was already declared with explicit size
+ extern int arr[10];
+ int arr[] = { 1,2,3 }; */
+ type->ref->c = sym->type.ref->c;
+ size = type_size(type, &align);
+ }
+ /* unshare type in case of:
+ typedef int key[];
+ key a; key b;
+ key a = { 1 }; key b = { 1, 2 };
+ */
+ sym->type.ref = sym_push(SYM_FIELD, &sym->type.ref->type,
+ 0, sym->type.ref->c);
}
patch_storage(sym, ad, type);
/* we accept several definitions of the same global variable.
*/
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel