mycc built-in field_sizeof(), sizeof struct field - Page 1
Forum section: electronics / general

author: DiTBho
author_rank: Super Contributor
timestamp: May 16, 2024, 09:55:28 am
content: so, in in mycc it's a build-in operator since the end of 2022Code:2022/12/20 query/lib_file_query_v1.c: mystring_clean(query_item.name, field_sizeof(file_query_item_t, name));2022/12/20 query/lib_file_query_v1.c: mystring_clean(query_item.mape, field_sizeof(file_query_item_t, mape));(first time I needed something like this, probably a silly case ...... anyway it's when I put the functionality in the compilerafter that I started using it wherever it is needed/makes the code more clean)Code:typedef struct{uint32_t fp;char_t name;char_t mape;uint32_t flags;uint32_t mode;boolean_t is_empty;} file_query_item_t;(xinu code)field_sizeof(file_query_item_t, name)retuns file_query_item_name_sizefield_sizeof(file_query_item_t, mape)retuns file_query_item_mape_sizeit's a *very* usefult feature!C/89 doesn't have it and in Linux you have to "emulate" it by thisCode:#define field_sizeof(t, f) (sizeof(((t*)0)->f))My opinion: this topic is informative, thefield_sizeof()operator should be built-in in every C/C-like compiler!

author: Nominal Animal
author_rank: Super Contributor
timestamp: May 16, 2024, 12:17:37 pm
content: Quote from: DiTBho on May 16, 2024, 09:55:28 amIn the C23 standard, however, footnote 4 explicitly states that(void *)0is valid in the operand ofalignas,alignof, andsizeofexpressions. Thus, in C23,#define field_sizeof(type, member) (sizeof ((type *)0)->member)can be understood/accepted as being valid (as long asmemberis not a variable length array at least).There are also quite a few userspace users of that, and in definitions of the relatedoffsetofmacro,#define offsetof(type, member) ((size_t) &(((type *)0)->member))so any compiler that cannot handle these will fail to compile quite lot of existing C code, too.(It is important to remember that aside from C11, the C standard has evolved by including stuff compilers have implemented and users use; not by defining or dictating completely new features not implemented yet by any compiler.)Quote from: DiTBho on May 16, 2024, 09:55:28 amAgreed.GCC has traditionally implemented many related operators as an extension to C:__alignof__, standardized in C11 as_Alignofand in C23 asalignof__alignas__, standardized in C11 as_Alignasand in C23 asalignastypeof, standardized in C23 astypeof(andtypeof_unqualfor the non-atomic unqualified type of the expression)which are similarly useful.typeofand compound statements in parentheses (another GCC extension) allow macros that only evaluate their parameters only once (as long as they are not variably modified types):#define foo(x, y) ({ typeof (x) _x = (x); typeof (y) _y = (y);use_xand_y ... ;result; })

author: SiliconWizard
author_rank: Super Contributor
timestamp: May 16, 2024, 11:04:08 pm
content: Yes, all this has been available on many C compilers for a long time, but was not strictly allowed by the C standard until C23.

author: DiTBho
author_rank: Super Contributor
timestamp: May 17, 2024, 01:09:59 pm
content: Code:mystring_clean(query_item.mape, file_query_item_t.name'size);2024/5/16: now, mycc can do this

author: DiTBho
author_rank: Super Contributor
timestamp: May 17, 2024, 01:13:14 pm
content: Quote from: SiliconWizard on May 16, 2024, 11:04:08 pmYup, the above trick (first post) is used in recent linux kernels, so I have already updated the builder database (which checks the environment before allowing the user to compile things) to make sure kernels and part of the Catalyst rootfs, which use the same trick, are compiled with the correct version of Gcc and right flags, in order to have C23 support.

author: S. Petrukhin
author_rank: Super Contributor
timestamp: May 17, 2024, 02:16:30 pm
content: IsSizeOf(file_query_item_t.name )doesn't work?P.S. I don't know much about C.

author: DiTBho
author_rank: Super Contributor
timestamp: May 17, 2024, 05:48:16 pm
content: Quote from: S. Petrukhin on May 17, 2024, 02:16:30 pmeh, if it was so intuitive ...unfortunately it doesn't work like that, look at how the macro is madeCode:#define field_sizeof(t, f) (sizeof(((t*)0)->f))you pass the struct type (t), and then the field (f).And it's already a miracle that it works.e.g. on SierraC, and on AvgetC (90s), the macro doesn't work at all.You need modern gcc/llvm, with C23 support!

author: DiTBho
author_rank: Super Contributor
timestamp: May 17, 2024, 05:51:10 pm
content: Quote from: DiTBho on May 17, 2024, 01:09:59 pm"mycc" is a compiler that I wrote; to achieve that result I had to completely change the approach.

author: ejeffrey
author_rank: Super Contributor
timestamp: May 17, 2024, 06:10:28 pm
content: Quote from: S. Petrukhin on May 17, 2024, 02:16:30 pmNo in C you can't use the . or -> operators on a type name, only in a value expression.

author: SiliconWizard
author_rank: Super Contributor
timestamp: May 17, 2024, 10:32:07 pm
content: Quote from: DiTBho on May 17, 2024, 05:51:10 pmSo you have added attributes in the Ada style. That's cool.

author: S. Petrukhin
author_rank: Super Contributor
timestamp: May 18, 2024, 09:35:58 am
content: The mice pricked and cried, but continued to eat the cactus.I'm sorry, I remembered a joke...Generating a type when describing a structure field is accessible, but ugly.In addition to the fact that it is not possible to take the size of the structure field as a variable, there is a type checking conflict when passing this field as a variable to the function.I think it will be more reliable and beautiful this way:Code:typename name_t;nape nape_t;typedef struct{uint32_t fp;name_t name;nape_t mape;} file_query_item_t;Having aname_tdefinition, you can use it when specifying function parameters and allow the compiler to check for compliance.