> On Aug 14, 2023, at 2:41 AM, Richard Biener via Gcc <gcc@gcc.gnu.org> wrote: > > On Fri, Aug 11, 2023 at 8:30 PM Alejandro Colomar via Gcc > <gcc@gcc.gnu.org> wrote: >> >> Hi! >> >> Structures with flexible array members have restrictions about being >> used in arrays or within other structures, as the size of the enclosing >> aggregate type would be... inconsistent. >> >> In general, sizeof(flexible_struct) is a problematic thing that rarely >> means what programmers think it means. It is not the size of the >> structure up to the flexible array member; or expressed using C, >> the following can be true: >> >> sizeof(s) != offsetof(s, fam) >> >> See the program at the bottom that demonstrates how this is problematic. >> >> It's true that if one uses >> >> malloc(offseof(s, fam) + sizeof_member(s, fam[0]) * N); >> >> and N is very small (0 or 1 usually), the allocation would be smaller >> than the object size, which for GCC seems to be fine, but I'm worried the >> standard is not clear enough about its validity[1]. >> >> [1]: <https://software.codidact.com/posts/287754> >> >> To avoid having UB there, pedantically one would need to call >> >> malloc(MAX(sizeof(s), offseof(s, fam) + sizeof_member(s, fam[0]) * >> N)); >> >> But I think that's the only correct use of sizeof() with structures >> containing flexible array members. So it seems sizeof() by itself is >> a valid thing, but when adding it to something else to get the total size, >> or doing any arithmetic with it, that's dubious code. >> >> How about some -Wfam-sizeof-arithmetic that would not warn about taking >> sizeof(s) but would warn if that sizeof is used in any arithmetic? > > There are probably many ways sizeof() plus arithmetic can yield a correct > size for allocation. After all _all_ uses of FAM requires allocation > and there's > no convenient standard way of calculating the required size (sizeof > (fam-type[n])?). > > Iff we want to diagnose anything then possibly a computation that looks like > a size computation but that's actually smaller than required,
Yes, I think that an warning on insufficient allocation might be useful in general, which might be combined with Martin’s previous proposed patch together: -Walloc_type? https://gcc.gnu.org/pipermail/gcc-patches/2023-July/625172.html Another thing is: is there a place in GCC’s doc where we can add some clarification or suggestion to the users on how to allocate space for structures with FAM? Looks like that this is a very confusion area.. thanks. Qing > but > other than that - what > would you suggest to fix such reported warnings? > > Richard. > >> Cheers, >> Alex >> >> --- >> >> $ cat off.c >> #include <err.h> >> #include <stddef.h> >> #include <stdio.h> >> #include <stdlib.h> >> #include <string.h> >> >> >> struct s { >> int i; >> char c; >> char fam[]; >> }; >> >> >> static inline void *xmalloc(size_t size); >> >> >> int >> main(void) >> { >> char *p; >> struct s *s; >> >> printf("sizeof: %zu\n", sizeof(struct s)); >> printf("offsetof: %zu\n", offsetof(struct s, fam)); >> >> puts("\nWith sizeof():"); >> >> s = xmalloc(sizeof(struct s) + sizeof("Hello, sizeof!")); >> strcpy(s->fam, "Hello, sizeof!"); >> p = (char *) s + sizeof(struct s); >> puts(p); >> free(s); >> >> puts("\nWith offsetof(3):"); >> >> s = xmalloc(offsetof(struct s, fam) + sizeof("Hello, offsetof!")); >> strcpy(s->fam, "Hello, offsetof!"); >> p = (char *) s + offsetof(struct s, fam); >> puts(p); >> free(s); >> >> exit(EXIT_SUCCESS); >> } >> >> >> static inline void * >> xmalloc(size_t size) >> { >> void *p; >> >> p = malloc(size); >> if (p == NULL) >> err(EXIT_FAILURE, "malloc"); >> return p; >> } >> $ gcc-13 -Wall -Wextra -Wpadded -fanalyzer off.c >> off.c:12:1: warning: padding struct size to alignment boundary with 3 bytes >> [-Wpadded] >> 12 | }; >> | ^ >> >> >> The only warning I know that is triggered in the code above is -Wpadded, >> which is related to this problem, but I think there should be something >> to warn about sizeof() in this context. >> >> >> -- >> <http://www.alejandro-colomar.es/> >> GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5