For Programmers: Free Programming Magazines  


Home > Archive > C > June 2006 > Constructor equivalent









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Constructor equivalent
Gernot Frisch

2006-06-27, 3:56 am


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%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}





Vladimir Oka

2006-06-27, 3:56 am


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:
>
code:
> struct foo > { > foo() {bar=0;} > int bar; > }; > > int main() > { > foo f[5]; > } >

>
> I would write:
>
code:
> struct foo > { > 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.

Gernot Frisch

2006-06-27, 3:56 am


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


Vladimir Oka

2006-06-27, 3:56 am


Gernot Frisch wrote:
>
> 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).

Thad Smith

2006-06-27, 7:56 am

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
Roberto Waltman

2006-06-27, 6:56 pm

"Gernot Frisch" wrote:
>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?


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

....
Gernot Frisch

2006-06-28, 7:57 am


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


Ian Collins

2006-06-28, 7:57 am

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

Correct.

--
Ian Collins.
pete

2006-06-28, 7:57 am

Ian Collins wrote:
>
> Gernot Frisch wrote:
> 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
Roberto Waltman

2006-06-28, 7:57 am

"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.
Ian Collins

2006-06-28, 6:56 pm

pete wrote:
> Ian Collins wrote:
>
>
>
> 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.
Tom Plunket

2006-06-28, 6:56 pm

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)


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!
Keith Thompson

2006-06-28, 6:56 pm

Ian Collins <ian-news@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) 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.
Ian Collins

2006-06-28, 6:56 pm

Keith Thompson wrote:
> Ian Collins <ian-news@hotmail.com> writes:
> [...]
>
>
>
> 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.
Gernot Frisch

2006-06-29, 7:56 am



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


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com