473,385 Members | 2,162 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Constructor equivalent


Hi,

since C does not support construcor functions for structs, what is the
usual approach to write this C++ code in C:
Expand|Select|Wrap|Line Numbers
  1. struct foo
  2. {
  3. foo() {bar=0;}
  4. int bar;
  5. };
  6.  
  7. int main()
  8. {
  9. foo f[5];
  10. }
  11.  
I would write:
Expand|Select|Wrap|Line Numbers
  1. struct foo
  2. {
  3. bar;
  4. };
  5.  
  6. Init(foo& f)
  7. {
  8. bar=0;
  9. }
  10.  
  11. int main(int, char**)
  12. {
  13. foo f[5];
  14. // Put this in a Macro: INIT(f)?
  15. for(int i=0; i<sizeof(f)/sizeof(f[0]); ++i)
  16. Init(f[i]);
  17. return 0;
  18. }
  19.  
Any better ideas?

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

Jun 27 '06 #1
14 1378

Gernot Frisch wrote:
Hi,

since C does not support construcor functions for structs, what is the
usual approach to write this C++ code in C:
Expand|Select|Wrap|Line Numbers
  1.  struct foo
  2.  {
  3.      foo() {bar=0;}
  4.      int bar;
  5.  };
  6.  int main()
  7.  {
  8.      foo f[5];
  9.  }
  10.  

I would write:
Expand|Select|Wrap|Line Numbers
  1.  struct foo
  2.  {
  3.      bar;
  •  
  • Her, I'd prefer
  •  
  • int bar;
  •  
  • It's always good to spell things out.
  •  };
  •  Init(foo& f)
  •  
  • void Init(foo *f)
  •  
  • Omitting function type defaults to `int` (which pre-C99 would require a
  • `return`).
  •  {
  •      bar=0;
  •  
  • Here, `bar` is unknown. Since it's a member of your struct, you'll
  • need:
  •  
  • f->bar = 0;
  •  }
  •  int main(int, char**)
  •  
  • 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).
  •  {
  •      foo f[5];
  •      // Put this in a Macro: INIT(f)?
  •  
  • I wouldn't. I also wouldn't use C99 comments, especially on Usenet.
  •      for(int i=0; i<sizeof(f)/sizeof(f[0]); ++i)
  •  
  • I'd also declare `i` outside of `for`, but that may be a matter of
  • taste.
  •         Init(f[i]);
  •  return 0;
  •  }
  •  

  • Any better ideas?

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

    Jun 27 '06 #2
    Any better ideas?


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


    I just woosh-woosh-typed that thing so you could get my point. Thank
    you for the clearing, though.
    Jun 27 '06 #3

    Gernot Frisch wrote:
    Any better ideas?


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


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


    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).

    Jun 27 '06 #4
    Gernot Frisch wrote:
    Hi,

    since C does not support construcor functions for structs, what is the
    usual approach to write this C++ code in C: .... 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?


    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
    Jun 27 '06 #5
    "Gernot Frisch" wrote:
    since C does not support construcor functions for structs, what is the
    usual approach to write this C++ code in C:
    Expand|Select|Wrap|Line Numbers
    1. struct foo
    2. {
    3.     foo() {bar=0;}
    4.     int bar;
    5. };
    6. int main()
    7. {
    8.     foo f[5];
    9. }

    I would write:
    Expand|Select|Wrap|Line Numbers
    1. struct foo
    2. {
    3.     bar;
    4. };
    5. Init(foo& f)
    6. {
    7.     bar=0;
    8. }
    9. int main(int, char**)
    10. {
    11.     foo f[5];
    12.     // Put this in a Macro: INIT(f)?
    13.     for(int i=0; i<sizeof(f)/sizeof(f[0]); ++i)
    14.        Init(f[i]);
    15. return 0;
    16. }

    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);
    }

    Similar code from a real project:

    ( Notes: was(Un)formatted 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_desc_s const * const desc);
    // ^- Initialization function.
    bool (*encode)(prv_msg_s * prv_msg,
    const ccs_msg_s * app_msg);
    // ^- Message encoding function.
    bool (*decode)(ccs_msg_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_msg_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_SIZE.
    // 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)(const prv_msg_s * prv_msg);
    // ^- Called before transmision for
    // message-specific post-processing.
    // NULL if not needed
    bool (*rx_process)(ccs_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_tx_prv_msg, com1_tx_app_msg);

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

    // call post-process function if neccessary
    if (desc->tx_process)
    {
    stat = (desc->tx_process)(com1_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_insert_errors++;
    continue;
    }

    ....
    Jun 27 '06 #6
    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(members) + sizeof(method_pointers), right? So, this might be
    inefficient for a device with 1K RAM, no? (not cynical - this is a
    true question)
    Jun 28 '06 #7
    Gernot Frisch wrote:
    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(members) + sizeof(method_pointers), right? So, this might be
    inefficient for a device with 1K RAM, no? (not cynical - this is a
    true question)

    Correct.

    --
    Ian Collins.
    Jun 28 '06 #8
    Ian Collins wrote:

    Gernot Frisch wrote:
    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(members) + sizeof(method_pointers), right? So, this might be
    inefficient for a device with 1K RAM, no? (not cynical - this is a
    true question)

    Correct.


    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
    Jun 28 '06 #9
    "Gernot Frisch" wrote:
    ...
    For programming a microcontroller: Every struct's sizeof() would be
    sizeof(members) + sizeof(method_pointers), right? So, this might be
    inefficient for a device with 1K RAM, no? (not cynical - this is a
    true question)


    I understand your question, but the wording is incorrect. The size of
    the structure is sizeof(the_structure).
    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.
    Jun 28 '06 #10
    pete wrote:
    Ian Collins wrote:
    Gernot Frisch wrote:
    >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(members) + sizeof(method_pointers), right? So, this might be
    inefficient for a device with 1K RAM, no? (not cynical - this is a
    true question)


    Correct.

    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.

    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.
    Jun 28 '06 #11
    Gernot Frisch wrote:
    struct foo
    {
    int bar;
    void (*init)(struct foo* this);
    };


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


    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!
    Jun 28 '06 #12
    Ian Collins <ia******@hotmail.com> writes:
    [...]
    The OP was differentiating between data members and function pointer
    members. I thought that was quite clear from the way he phrased his
    question.


    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_Keith) ks***@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.
    Jun 28 '06 #13
    Keith Thompson wrote:
    Ian Collins <ia******@hotmail.com> writes:
    [...]
    The OP was differentiating between data members and function pointer
    members. I thought that was quite clear from the way he phrased his
    question.

    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.)

    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.
    Jun 28 '06 #14

    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.


    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.
    Jun 29 '06 #15

    This thread has been closed and replies have been disabled. Please start a new discussion.

    Similar topics

    9
    by: Xiangliang Meng | last post by:
    The fragment code: #include <iostream> using namespace std; class Integer { int i; public: Integer() : i(0) {};
    29
    by: Ioannis Vranos | last post by:
    I was confused from another thread about this: Does this kind of initialisation int x= int(); initialise to 0 of the type only for built in types or for *all* POD types?
    16
    by: jonathan cano | last post by:
    QUESTION: In practice, lines 36 and 37 below are usually equivalent to the default copy constructor (.e.g line 33). My questions are: (a) Does ISO 14882 guarantee that lines 36 and 37 are...
    34
    by: Jason Heyes | last post by:
    Is there a special name for a constructor that does struct-like initialisation? Example: class DefaultCtor { std::string class_name; bool compiler_generated; public:...
    14
    by: Arne | last post by:
    In C++ we have a copy constructor. What is the equivalent in .Net? Would that be a clone method?
    5
    by: Edward Diener | last post by:
    The first type to a delegate constructor is obvious. It is a System::Object * . What is the MC++ type of the second argument to the delegate constructor ? In C++ it would be a member function...
    10
    by: Szabolcs Horvát | last post by:
    Consider the attached example program: an object of type 'A' is inserted into a 'map<int, Am;'. Why does 'm;' call the copy constructor of 'A' twice in addition to a constructor call? The...
    9
    by: campos | last post by:
    Here are my codes: #include <iostream> using namespace std; class Test { public: Test() { cout << "Test()" << endl; }
    7
    by: dragoncoder | last post by:
    Hello experts, I have the following code me. =cat mystring.h #include<iostream> using namespace std; class mystring {
    6
    by: PLS | last post by:
    I'm converting a piece of c++ code to C#. There's one part I'm having a problem with. There is a class A which can be created only by calling a class factory method on object B. Things won't...
    0
    by: taylorcarr | last post by:
    A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
    0
    by: Charles Arthur | last post by:
    How do i turn on java script on a villaon, callus and itel keypad mobile phone
    0
    by: ryjfgjl | last post by:
    If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
    0
    by: ryjfgjl | last post by:
    In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
    0
    by: emmanuelkatto | last post by:
    Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
    1
    by: Sonnysonu | last post by:
    This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
    0
    by: Hystou | last post by:
    Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
    0
    Oralloy
    by: Oralloy | last post by:
    Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
    0
    jinu1996
    by: jinu1996 | last post by:
    In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

    By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

    To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.