Constructor equivalent

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gernot Frisch

    Constructor equivalent


    Hi,

    since C does not support construcor functions for structs, what is the
    usual approach to write this C++ code in C:
    Code:
    struct foo
    {
    foo() {bar=0;}
    int bar;
    };
    
    int main()
    {
    foo f[5];
    }
    I would write:
    Code:
    struct foo
    {
    bar;
    };
    
    Init(foo& f)
    {
    bar=0;
    }
    
    int main(int, char**)
    {
    foo f[5];
    // Put this in a Macro: INIT(f)?
    for(int i=0; i<sizeof(f)/sizeof(f[0]); ++i)
    Init(f[i]);
    return 0;
    }
    Any better ideas?



    --
    -Gernot
    int main(int argc, char** argv) {printf
    ("%silto%c%cf%c gl%ssic%ccom%c" , "ma", 58, 'g', 64, "ba", 46, 10);}





  • Vladimir Oka

    #2
    Re: Constructor equivalent


    Gernot Frisch wrote:[color=blue]
    > Hi,
    >
    > since C does not support construcor functions for structs, what is the
    > usual approach to write this C++ code in C:
    >
    Code:
    > struct foo
    > {
    >     foo() {bar=0;}
    >     int bar;
    > };
    >
    > int main()
    > {
    >     foo f[5];
    > }
    >
    >
    > I would write:
    >
    Code:
    > struct foo
    > {
    >     bar;[/color]
    
    Her, I'd prefer
    
    int bar;
    
    It's always good to spell things out.
    [color=blue]
    > };
    >
    > Init(foo& f)[/color]
    
    void Init(foo *f)
    
    Omitting function type defaults to `int` (which pre-C99 would require a
    `return`).
    [color=blue]
    > {
    >     bar=0;[/color]
    
    Here, `bar` is unknown. Since it's a member of your struct, you'll
    need:
    
    f->bar = 0;
    [color=blue]
    > }
    >
    > int main(int, char**)[/color]
    
    int main(int argc, char **argv)
    
    You need this here, as it's definition, not just declaration.
    Otherwise, how do you expect to refer to the two parameters below (it
    doesn't matter that you actually don't).
    [color=blue]
    > {
    >     foo f[5];
    >     // Put this in a Macro: INIT(f)?[/color]
    
    I wouldn't. I also wouldn't use C99 comments, especially on Usenet.
    [color=blue]
    >     for(int i=0; i<sizeof(f)/sizeof(f[0]); ++i)[/color]
    
    I'd also declare `i` outside of `for`, but that may be a matter of
    taste.
    [color=blue]
    >        Init(f[i]);
    > return 0;
    > }
    >
    >
    > Any better ideas?[/color]

    Yours seems to be OK, apart from apparent inexperience in C.

    Comment

    • Gernot Frisch

      #3
      Re: Constructor equivalent

      [color=blue][color=green]
      >> Any better ideas?[/color]
      >
      > Yours seems to be OK, apart from apparent inexperience in C.[/color]

      I just woosh-woosh-typed that thing so you could get my point. Thank
      you for the clearing, though.


      Comment

      • Vladimir Oka

        #4
        Re: Constructor equivalent


        Gernot Frisch wrote:[color=blue][color=green][color=darkred]
        > >> Any better ideas?[/color]
        > >
        > > Yours seems to be OK, apart from apparent inexperience in C.[/color]
        >
        > I just woosh-woosh-typed that thing so you could get my point. Thank
        > you for the clearing, though.[/color]

        I guessed as much, hence "apparent". It saves everybody's time if you
        try to post as correct code as possible (i.e. no silly woosh-woosh
        errors ;-) ). As you probably know, in c.l.c even the smallest of
        things get corrected (a Good Thing).

        Comment

        • Thad Smith

          #5
          Re: Constructor equivalent

          Gernot Frisch wrote:[color=blue]
          > Hi,
          >
          > since C does not support construcor functions for structs, what is the
          > usual approach to write this C++ code in C:[/color]
          ....[color=blue]
          > int main(int, char**)
          > {
          > foo f[5];
          > // Put this in a Macro: INIT(f)?
          > for(int i=0; i<sizeof(f)/sizeof(f[0]); ++i)
          > Init(f[i]);
          > return 0;
          > }
          > [/code]
          >
          > Any better ideas?[/color]

          Typically, I would have a module foo.c. It would declare
          struct foo;
          FooInit(struct *foo foop);
          FooGroom (struct *foo foop, int bar);
          etc.

          --
          Thad

          Comment

          • Roberto Waltman

            #6
            Re: Constructor equivalent

            "Gernot Frisch" wrote:[color=blue]
            >since C does not support construcor functions for structs, what is the
            >usual approach to write this C++ code in C:
            >
            Code:
            >struct foo
            >{
            >    foo() {bar=0;}
            >    int bar;
            >};
            >
            >int main()
            >{
            >    foo f[5];
            >}
            >
            >
            >I would write:
            >
            Code:
            >struct foo
            >{
            >    bar;
            >};
            >
            >Init(foo& f)
            >{
            >    bar=0;
            >}
            >
            >int main(int, char**)
            >{
            >    foo f[5];
            >    // Put this in a Macro: INIT(f)?
            >    for(int i=0; i<sizeof(f)/sizeof(f[0]); ++i)
            >       Init(f[i]);
            >return 0;
            >}
            >
            >
            >Any better ideas?[/color]

            Yes. Do you own "C with classes" as C-front did. Include methods in
            the structure as function pointers, with an explicit parameter for the
            struct itself. (Replacing "this".)

            struct foo
            {
            int bar;
            void (*init)(struct foo* this);
            };

            int main()
            {
            struct foo f;
            ...
            f.init(&f);
            }

            Similar code from a real project:

            ( Notes: was(Un)formatte d to fit here, will not compile as-is, several
            typedefs and definitions missing.)

            =============== =============

            //--------------------------------------------------------------
            // message descriptor structure
            //--------------------------------------------------------------

            typedef struct msg_desc msg_desc_s;

            struct msg_desc
            {
            msg_type_e type; // <- Message type (id for
            // internal system transfers).
            uint16_t code; // <- Message code (id for on-the
            // -wire transfers).
            uint16_t code_mask;// <- Bit mask to extract code.
            char *name; // <- Message name. For debugging
            // only, can be removed if we
            // run short of memory.
            bool (*init)(msg_des c_s const * const desc);
            // ^- Initialization function.
            bool (*encode)(prv_m sg_s * prv_msg,
            const ccs_msg_s * app_msg);
            // ^- Message encoding function.
            bool (*decode)(ccs_m sg_s * app_msg,
            const prv_msg_s * prv_msg);
            // ^- Message decoding function.
            bool (*time_update)( isr_msg_s * isr_msg);
            // ^- Time update function. Called
            // by the transmit ISR immediately
            // before delivering a message to
            // the FPGA. NULL for
            // messages that do not carry
            // timing information
            bool (*insert)(prv_m sg_s * fifo,
            const prv_msg_s * prv_msg);
            // ^- Function to insert message
            // in transmit fifo.
            // Normally points to fifo_insert(),
            // but can be replaced to implement
            // message type specific fifo
            // bumping/replacement policies.
            uint16_t leng; // <- Message length.
            uint16_t repeat; // <- Number of time message should be
            // repeated.
            uint16_t flags; // <- Message flags. //%TODO% - define,
            // remove?
            bool keep; // <- If true do not remove from
            // fifo after transmission (for
            // messages that need
            // acknowledgement , etc.)
            prv_msg_s *fifo; // <- Pointer to per type message
            // transmit fifo.
            uint16_t fifo_size;// <- Fifo size. Today all fifos
            // are of size COM_TX_FIFO_SIZ E.
            // This is a place holder to
            // allow per-message-type fifo
            // sizes in the future.
            uint16_t ttl; // <- Message time to live. If a
            // message remains in a transmit
            // fifo longer than this time,
            // (most likely because of higher
            // priority messages being
            // transmitted ahead of it,) it
            // will be deleted.
            bool can_abort;// <- If true, message transmition
            // can be aborted when higher
            // priority messages are pending.
            // Valid only for messages of
            // leng > 1 - (*NOT* used yet)
            uint16_t rx_mbx; // <- Receive mailbox index
            uint16_t msg_delay;// <- Minimum intermessage delay
            bool (*tx_process)(c onst prv_msg_s * prv_msg);
            // ^- Called before transmision for
            // message-specific post-processing.
            // NULL if not needed
            bool (*rx_process)(c cs_msg_s * app_msg,
            const prv_msg_s * prv_msg);
            // ^- Called after receiving for
            // message-specific post-processing
            // NULL if not needed
            msg_stats_s *stats; // <- Per-message statistics block
            };

            =============== =============

            Sample usage:
            msg_desc_s *desc = ...;
            bool stat;

            ....
            // encode message
            stat = (desc->encode)(com1_t x_prv_msg, com1_tx_app_msg );

            // encoding errors ?
            if (!stat)
            {
            // yes, update error counters & exit
            desc->stats->txtsk_encode_e rrors++;
            continue;
            }

            // call post-process function if neccessary
            if (desc->tx_process)
            {
            stat = (desc->tx_process)(co m1_tx_prv_msg);
            // post-process errors?
            if (!stat)
            {
            // yes, update error counters and exit
            // without updating transmit fifos
            desc->stats->txtsk_process_ errors++;
            continue;
            }
            }

            // insert in fifo for transmission
            stat = (desc->insert)(desc->fifo, com1_tx_prv_msg );

            // insertion failed ?
            if (!stat)
            {
            // yes, update error counters & exit
            desc->stats->txtsk_fifo_ins ert_errors++;
            continue;
            }

            ....

            Comment

            • Gernot Frisch

              #7
              Re: Constructor equivalent

              [color=blue][color=green]
              >>Any better ideas?[/color]
              >
              > Yes. Do you own "C with classes" as C-front did. Include methods in
              > the structure as function pointers, with an explicit parameter for
              > the
              > struct itself. (Replacing "this".)
              >
              > struct foo
              > {
              > int bar;
              > void (*init)(struct foo* this);
              > };
              >
              > int main()
              > {
              > struct foo f;
              > ...
              > f.init(&f);
              > }[/color]

              For programming a microcontroller : Every struct's sizeof() would be
              sizeof(members) + sizeof(method_p ointers), right? So, this might be
              inefficient for a device with 1K RAM, no? (not cynical - this is a
              true question)


              Comment

              • Ian Collins

                #8
                Re: Constructor equivalent

                Gernot Frisch wrote:[color=blue][color=green][color=darkred]
                >>>Any better ideas?[/color]
                >>
                >>Yes. Do you own "C with classes" as C-front did. Include methods in
                >>the structure as function pointers, with an explicit parameter for
                >>the
                >>struct itself. (Replacing "this".)
                >>
                >>struct foo
                >>{
                >> int bar;
                >> void (*init)(struct foo* this);
                >>};
                >>
                >>int main()
                >>{
                >> struct foo f;
                >> ...
                >> f.init(&f);
                >>}[/color]
                >
                >
                > For programming a microcontroller : Every struct's sizeof() would be
                > sizeof(members) + sizeof(method_p ointers), right? So, this might be
                > inefficient for a device with 1K RAM, no? (not cynical - this is a
                > true question)
                >[/color]
                Correct.

                --
                Ian Collins.

                Comment

                • pete

                  #9
                  Re: Constructor equivalent

                  Ian Collins wrote:[color=blue]
                  >
                  > Gernot Frisch wrote:[color=green][color=darkred]
                  > >>>Any better ideas?
                  > >>
                  > >>Yes. Do you own "C with classes" as C-front did. Include methods in
                  > >>the structure as function pointers,
                  > >>with an explicit parameter for the
                  > >>struct itself. (Replacing "this".)
                  > >>
                  > >>struct foo
                  > >>{
                  > >> int bar;
                  > >> void (*init)(struct foo* this);
                  > >>};
                  > >>
                  > >>int main()
                  > >>{
                  > >> struct foo f;
                  > >> ...
                  > >> f.init(&f);
                  > >>}[/color]
                  > >
                  > >
                  > > For programming a microcontroller : Every struct's sizeof() would be
                  > > sizeof(members) + sizeof(method_p ointers), right? So, this might be
                  > > inefficient for a device with 1K RAM, no? (not cynical - this is a
                  > > true question)
                  > >[/color]
                  > Correct.[/color]

                  What are you talking about?
                  The size of a struct is the size of the members
                  plus the padding bytes.

                  For the code shown above,
                  bar is one member of the struct, init is the other.

                  --
                  pete

                  Comment

                  • Roberto Waltman

                    #10
                    Re: Constructor equivalent

                    "Gernot Frisch" wrote:[color=blue]
                    >...
                    >For programming a microcontroller : Every struct's sizeof() would be
                    >sizeof(members ) + sizeof(method_p ointers), right? So, this might be
                    >inefficient for a device with 1K RAM, no? (not cynical - this is a
                    >true question)[/color]

                    I understand your question, but the wording is incorrect. The size of
                    the structure is sizeof(the_stru cture).
                    Yes, it is going to be larger if pointer to method functions are
                    included per my suggestion.
                    And yes, it is not a good suggestion is memory size is critical.

                    Comment

                    • Ian Collins

                      #11
                      Re: Constructor equivalent

                      pete wrote:[color=blue]
                      > Ian Collins wrote:
                      >[color=green]
                      >>Gernot Frisch wrote:
                      >>[color=darkred]
                      >>>>>Any better ideas?
                      >>>>
                      >>>>Yes. Do you own "C with classes" as C-front did. Include methods in
                      >>>>the structure as function pointers,
                      >>>>with an explicit parameter for the
                      >>>>struct itself. (Replacing "this".)
                      >>>>
                      >>>>struct foo
                      >>>>{
                      >>>> int bar;
                      >>>> void (*init)(struct foo* this);
                      >>>>};
                      >>>>
                      >>>>int main()
                      >>>>{
                      >>>> struct foo f;
                      >>>> ...
                      >>>> f.init(&f);
                      >>>>}
                      >>>
                      >>>
                      >>>For programming a microcontroller : Every struct's sizeof() would be
                      >>>sizeof(membe rs) + sizeof(method_p ointers), right? So, this might be
                      >>>inefficien t for a device with 1K RAM, no? (not cynical - this is a
                      >>>true question)
                      >>>[/color]
                      >>
                      >>Correct.[/color]
                      >
                      >
                      > What are you talking about?
                      > The size of a struct is the size of the members
                      > plus the padding bytes.
                      >
                      > For the code shown above,
                      > bar is one member of the struct, init is the other.
                      >[/color]
                      The OP was differentiating between data members and function pointer
                      members. I thought that was quite clear from the way he phrased his
                      question.

                      --
                      Ian Collins.

                      Comment

                      • Tom Plunket

                        #12
                        Re: Constructor equivalent

                        Gernot Frisch wrote:
                        [color=blue][color=green]
                        >> struct foo
                        >> {
                        >> int bar;
                        >> void (*init)(struct foo* this);
                        >> };
                        >>[/color]
                        >
                        >For programming a microcontroller : Every struct's sizeof() would be
                        >sizeof(members ) + sizeof(method_p ointers), right? So, this might be
                        >inefficient for a device with 1K RAM, no? (not cynical - this is a
                        >true question)[/color]

                        Right, this would be an ok way to do virtual functions, for instance,
                        but the facility with an init function isn't really useful since you
                        need to know how to init the thing before the pointer will be set in
                        the first place!

                        E.g. it is not entirely valid to do:

                        int main(void)
                        {
                        foo f;
                        f.init(&f);
                        }

                        ....since f hasn't been initialized in any way, and init doesn't point
                        at anything defined.

                        -tom!

                        Comment

                        • Keith Thompson

                          #13
                          Re: Constructor equivalent

                          Ian Collins <ian-news@hotmail.co m> writes:
                          [...][color=blue]
                          > The OP was differentiating between data members and function pointer
                          > members. I thought that was quite clear from the way he phrased his
                          > question.[/color]

                          Sure, but C makes no such distinction; function pointer members are
                          data members. (I understand that C++ introduces some more complexity
                          in this area, with some members possibly being implicit.)

                          --
                          Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                          San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
                          We must do something. This is something. Therefore, we must do this.

                          Comment

                          • Ian Collins

                            #14
                            Re: Constructor equivalent

                            Keith Thompson wrote:[color=blue]
                            > Ian Collins <ian-news@hotmail.co m> writes:
                            > [...]
                            >[color=green]
                            >>The OP was differentiating between data members and function pointer
                            >>members. I thought that was quite clear from the way he phrased his
                            >>question.[/color]
                            >
                            >
                            > Sure, but C makes no such distinction; function pointer members are
                            > data members. (I understand that C++ introduces some more complexity
                            > in this area, with some members possibly being implicit.)
                            >[/color]
                            That was probably the clarification he required, doing "C with classes"
                            has a cost in the form of the function pointer members of the struct.
                            This isn't the case in C++, so this cost is something someone form a C++
                            background might overlook.

                            Cheers,

                            --
                            Ian Collins.

                            Comment

                            • Gernot Frisch

                              #15
                              Re: Constructor equivalent


                              [color=blue]
                              > int main(void)
                              > {
                              > foo f;
                              > f.init(&f);
                              > }
                              >
                              > ...since f hasn't been initialized in any way, and init doesn't
                              > point
                              > at anything defined.[/color]

                              Right. So I need an pre-initializer as well. My question was just
                              about the c'tor for an array of structs, so I see, there's not other
                              way then just looping through each element and initialize it with a
                              function.

                              Thank you all. I though so, but I wanted to not overlook something.


                              Comment

                              Working...