• c initialization algorithm

    From Thiago Adams@thiago.adams@gmail.com to comp.lang.c on Sun Oct 13 18:35:03 2024
    From Newsgroup: comp.lang.c

    The algorithm for C initialization as described in the standard and implemented in gcc allow this.

    struct X{
    int a,b,c;
    };

    int main()
    {
    struct X x = {.a=1,2,3,.a=1, 2, 3};
    }

    https://godbolt.org/z/7naedbEM6

    Basically, when a designed initializer is found the "cursor" goes to
    that member and the following members are initialized in order.

    struct X{
    int a,b,c;
    };

    int main()
    {
    struct X x = {.a=1,2,3,.a=1, 2, 3, .a=1, 4, 5};
    }
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.lang.c on Sun Oct 13 23:33:04 2024
    From Newsgroup: comp.lang.c

    On 2024-10-13, Thiago Adams <thiago.adams@gmail.com> wrote:
    The algorithm for C initialization as described in the standard and implemented in gcc allow this.

    struct X{
    int a,b,c;
    };

    int main()
    {
    struct X x = {.a=1,2,3,.a=1, 2, 3};
    }

    https://godbolt.org/z/7naedbEM6

    Basically, when a designed initializer is found the "cursor" goes to
    that member and the following members are initialized in order.

    I do not suspect that therw is an observable order. I.e. as
    in a required order considered observable behavior.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Sun Oct 13 22:00:39 2024
    From Newsgroup: comp.lang.c

    Kaz Kylheku <643-408-1753@kylheku.com> writes:

    On 2024-10-13, Thiago Adams <thiago.adams@gmail.com> wrote:

    The algorithm for C initialization as described in the standard
    and implemented in gcc allow this.

    struct X{
    int a,b,c;
    };

    int main()
    {
    struct X x = {.a=1,2,3,.a=1, 2, 3};
    }

    https://godbolt.org/z/7naedbEM6

    Basically, when a designed initializer is found the "cursor" goes
    to that member and the following members are initialized in
    order.

    I do not suspect that therw is an observable order. I.e. as
    in a required order considered observable behavior.

    Have you checked to C standard to see what it says about that?
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Thiago Adams@thiago.adams@gmail.com to comp.lang.c on Mon Oct 14 08:14:40 2024
    From Newsgroup: comp.lang.c

    On 14/10/2024 02:00, Tim Rentsch wrote:
    Kaz Kylheku <643-408-1753@kylheku.com> writes:

    On 2024-10-13, Thiago Adams <thiago.adams@gmail.com> wrote:

    The algorithm for C initialization as described in the standard
    and implemented in gcc allow this.

    struct X{
    int a,b,c;
    };

    int main()
    {
    struct X x = {.a=1,2,3,.a=1, 2, 3};
    }

    https://godbolt.org/z/7naedbEM6

    Basically, when a designed initializer is found the "cursor" goes
    to that member and the following members are initialized in
    order.

    I do not suspect that therw is an observable order. I.e. as
    in a required order considered observable behavior.

    Have you checked to C standard to see what it says about that?

    I think these parts are relevant.

    "
    Each brace-enclosed initializer list has an associated current object.
    When no designations are present, subobjects of the current object are initialized in order according to the type of the current object:
    array elements in increasing subscript order, structure members in
    declaration order, and the first named member of a union.167) In
    contrast, a designation causes the following initializer to begin initialization of the subobject described by the designator.
    Initialization then continues forward in order, beginning with the next subobject after that described by the designator.168)
    "

    The initialization shall occur in initializer list order, each
    initializer provided for a particular subobject
    overriding any previously listed initializer for the same subobject;170)
    all subobjects that are not
    initialized explicitly are subject to default initialization.
    "

    "170: Any initializer for the subobject which is overridden and so not
    used to initialize that subobject may not be evaluated at all. "


    This last part made me create this sample in GCC. Reading it seems like
    it could potentially use the previous value.


    #include <stdio.h>

    struct X {
    int a, b;
    };

    int main()
    {
    const struct X x2 = { .a=1, .b = x2.a, .a =2 };
    printf("a=%d b=%d", x2.a, x2.b); //a=2 b=2
    }

    https://godbolt.org/z/6K7xKqh86



    clang shows when something is overridden.



    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Thiago Adams@thiago.adams@gmail.com to comp.lang.c on Tue Oct 15 08:12:35 2024
    From Newsgroup: comp.lang.c

    On 14/10/2024 08:14, Thiago Adams wrote:
    On 14/10/2024 02:00, Tim Rentsch wrote:
    Kaz Kylheku <643-408-1753@kylheku.com> writes:

    On 2024-10-13, Thiago Adams <thiago.adams@gmail.com> wrote:

    The algorithm for C initialization as described in the standard
    and implemented in gcc allow this.

    struct X{
          int a,b,c;
    };

    int main()
    {
          struct X x = {.a=1,2,3,.a=1, 2, 3};
    }

    https://godbolt.org/z/7naedbEM6

    Basically, when a designed initializer is found the "cursor" goes
    to that member and the following members are initialized in
    order.

      I do not suspect that therw is an observable order.  I.e. as
      in a required order considered observable behavior.

    Have you checked to C standard to see what it says about that?

    I'm not only interested in this part, but since it raised some doubts, I decided to do some checks

    #include <stdio.h>

    struct X {
    int i;
    };

    int f() {
    printf("f");
    return 1;
    }

    int main() {
    struct X x = {.i = f(), .i = f() };
    }

    https://godbolt.org/z/rf984cGMM

    There is a warning in this sample and f is called just once.



    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Thiago Adams@thiago.adams@gmail.com to comp.lang.c on Tue Oct 15 08:14:46 2024
    From Newsgroup: comp.lang.c

    On 15/10/2024 08:12, Thiago Adams wrote:
    On 14/10/2024 08:14, Thiago Adams wrote:
    On 14/10/2024 02:00, Tim Rentsch wrote:
    Kaz Kylheku <643-408-1753@kylheku.com> writes:

    On 2024-10-13, Thiago Adams <thiago.adams@gmail.com> wrote:

    The algorithm for C initialization as described in the standard
    and implemented in gcc allow this.

    struct X{
          int a,b,c;
    };

    int main()
    {
          struct X x = {.a=1,2,3,.a=1, 2, 3};
    }

    https://godbolt.org/z/7naedbEM6

    Basically, when a designed initializer is found the "cursor" goes
    to that member and the following members are initialized in
    order.

      I do not suspect that therw is an observable order.  I.e. as
      in a required order considered observable behavior.

    Have you checked to C standard to see what it says about that?

    I'm not only interested in this part, but since it raised some doubts, I decided to do some checks

    #include <stdio.h>

    struct X {
        int i;
    };

    int f() {
        printf("f");
        return 1;
    }

    int main() {
        struct X x = {.i = f(), .i = f() };
    }

    https://godbolt.org/z/rf984cGMM

    There is a warning in this sample and f is called just once.



    Forgot to say that I didn't find this part on the standard.
    I think initialization is also very superficial on books.

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.lang.c on Tue Oct 15 20:30:43 2024
    From Newsgroup: comp.lang.c

    On 2024-10-15, Thiago Adams <thiago.adams@gmail.com> wrote:
    int main() {
        struct X x = {.i = f(), .i = f() };
    }

    https://godbolt.org/z/rf984cGMM

    There is a warning in this sample and f is called just once.



    Forgot to say that I didn't find this part on the standard.
    I think initialization is also very superficial on books.

    The current public draft, which I think is still N3047, does
    address the issue of repeated mentions of the same subobject in
    a designated initializer:

    The initialization shall occur in initializer list order, each
    initializer provided for a particular subobject overriding any
    previously listed initializer for the same subobject.(184)

    Since the second .i = f() overrides the previously listed .i = f(),
    there is only one initialization of .i.

    It is not specified whether both calls to f() occur; i.e.
    is the initializing expression of the overridden initializer still
    evaluated?

    The referenced footnoted 184 address itself to this question.
    But not only is the footnote not normative text, as you know,
    it uses the phrase "might not", thus only clarifying that this
    aspect is not specified. f could be called twice or only once:

    184. Any initializer for the subobject which is overridden and
    so not used to initialize that subobject might not be evaluated at
    all.

    Don't write code that initializes subobjects more than once, or else if
    you do, don't have side effects in the initializing expressions such
    that the program depends on all of them being invoked.

    The implementation's warning is a good idea.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.20a-Linux NewsLink 1.114