> 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

Reply via email to