Connecting Tech Pros Worldwide Forums | Help | Site Map

Port code from C++ to C?

PengYu.UT@gmail.com
Guest
 
Posts: n/a
#1: Nov 14 '05
Hi,

I have to use some machine with only support of C. But I have some C++
programs, which use most C++ comman features. Is there any way to
convert those C++ programs to C?

Or is there any way that I can mimic C++ by C? So that even if I have
to recode, I don't have to change the C++ code structures.

Thanks!

Best wishes,
Peng


Walter Roberson
Guest
 
Posts: n/a
#2: Nov 14 '05

re: Port code from C++ to C?


In article <1116980947.994477.205040@g49g2000cwa.googlegroups .com>,
PengYu.UT@gmail.com <PengYu.UT@gmail.com> wrote:[color=blue]
>I have to use some machine with only support of C. But I have some C++
>programs, which use most C++ comman features. Is there any way to
>convert those C++ programs to C?[/color]

Please see the thread starting from
http://groups.google.ca/group/comp.l...592bd669995492
--
"Who Leads?" / "The men who must... driven men, compelled men."
"Freak men."
"You're all freaks, sir. But you always have been freaks.
Life is a freak. That's its hope and glory." -- Alfred Bester, TSMD
PengYu.UT@gmail.com
Guest
 
Posts: n/a
#3: Nov 14 '05

re: Port code from C++ to C?


Thank you for your reply! But this thread doesn't address all I want.

Not only I want port C++ to C (not necessarily by a preprocessor), I
also want the C code human readable.

So the problem right now is that how to implement OO in C language.
I've read some old OO book which discuss this issue, because there were
no enough OO support at that time. But I forget the title of the book.

If you can give me any relevant information, it will be great.

Peng

Walter Roberson
Guest
 
Posts: n/a
#4: Nov 14 '05

re: Port code from C++ to C?


In article <1116983922.700228.203240@g14g2000cwa.googlegroups .com>,
PengYu.UT@gmail.com <PengYu.UT@gmail.com> wrote:[color=blue]
>Thank you for your reply! But this thread doesn't address all I want.[/color]
[color=blue]
>Not only I want port C++ to C (not necessarily by a preprocessor), I
>also want the C code human readable.[/color]

You indicated that you wanted to mimic C++ in C. The result is
not very likely to be human readable.

[color=blue]
>So the problem right now is that how to implement OO in C language.[/color]

Don't. If you need C++ then use C++. If you don't need C++ then
write in C paradigms, not in C++ paradigms. Any attempt to write a
hybrid is likely to end up with ugly code.
--
I was very young in those days, but I was also rather dim.
-- Christopher Priest
gooch
Guest
 
Posts: n/a
#5: Nov 14 '05

re: Port code from C++ to C?




PengYu.UT@gmail.com wrote:[color=blue]
> Thank you for your reply! But this thread doesn't address all I want.
>
> Not only I want port C++ to C (not necessarily by a preprocessor), I
> also want the C code human readable.
>
> So the problem right now is that how to implement OO in C language.
> I've read some old OO book which discuss this issue, because there were
> no enough OO support at that time. But I forget the title of the book.
>
> If you can give me any relevant information, it will be great.
>
> Peng[/color]

You can do everything with C that you can do with C++ but if the code
is heavily dependent on OO features of C++ it is likely to be very
difficult to read if you simply translate it as is to C. You are
probably better of reverse engineering it and developing a design from
the existing C++ code and then adjusting the design to be implemented
in C using its strengths and then re-coding it.

John Devereux
Guest
 
Posts: n/a
#6: Nov 14 '05

re: Port code from C++ to C?


"PengYu.UT@gmail.com" <PengYu.UT@gmail.com> writes:
[color=blue]
> Thank you for your reply! But this thread doesn't address all I want.
>
> Not only I want port C++ to C (not necessarily by a preprocessor), I
> also want the C code human readable.
>
> So the problem right now is that how to implement OO in C language.
> I've read some old OO book which discuss this issue, because there were
> no enough OO support at that time. But I forget the title of the book.[/color]

Miro Samek discussed this extensively as part of his book "Practical
Statecharts in C/C++". He called the implementation "C+". You can
download the manual and source code from his web site
<http://www.quantum-leaps.com/devzone/cookbook.htm#OOP>.

--

John Devereux
PengYu.UT@gmail.com
Guest
 
Posts: n/a
#7: Nov 14 '05

re: Port code from C++ to C?


I'm sorry that I cann't download this manual. It seems the above link
is dead. If you have a copy would please email it to me as attachment.
Thanks,

Peng

Jonathan Bartlett
Guest
 
Posts: n/a
#8: Nov 14 '05

re: Port code from C++ to C?


To do OO in C, you usually do something like this:

C++ Class
---------
class foo
{
int a;
virtual void bar() { a = 3; }
virtual void abc() { a = 4; }
};

class doo : public foo
{
int b;
void bar() { b = 5; } /* overrides the original bar */
virtual void xzy() { b = 6; }
};

The C Version:
--------------
struct foo;
struct vtable_foo
{
void (*bar)(struct foo*);
void (*abc)(struct foo*);
};
struct vtable_foo __vtable_foo;

struct foo
{
struct vtable_foo *vtbl;
int a;
};

void foo_bar(struct foo *f)
{
f->a = 3;
}

void foo_abc(struct foo *f)
{
f->a = 4;
}

/* class initializer -- must be run EXACTLY ONCE before creating any
instances of foo */
void initialize_foo_class()
{
__vtable_foo.bar = foo_bar;
__vtable_foo.abc = foo_abc;
}

/* constructor */
void foo_initialize(struct foo *f)
{
f->vtbl = &__vtable_foo;
f->a = 0;
}

struct doo;
struct vtable_doo
{
void (*bar)(struct doo*);
void (*abc)(struct doo*);
void (*xyz)(struct doo*);
};
struct vtable_doo __vtable_doo;

struct doo
{
struct vtable_doo *vtbl;
int a; /* from foo */
int b;
};

void doo_bar(struct doo *d)
{
d->b = 5;
}

void doo_xyz(struct doo *d)
{
d->b = 6;
}

void initialize_doo_class()
{
/* inherited from foo */
__vtable_doo.bar = doo_bar; /* overriden in doo */
__vtable_doo.abc = foo_abc;

/* new in doo */
__vtable_doo.xyz = doo_xyz;
}

void doo_initialize(struct doo *d)
{
d->vtbl = &__vtable_doo;
d->a = 0;
d->b = 0;
}

int main()
{
struct foo *f1;
struct foo *f2;
struct doo *d1;

initialize_foo_class();
initialize_doo_class();

d1 = malloc(sizeof(struct doo));
doo_initialize(d1);
f1 = malloc(sizeof(struct foo));
foo_initialize(f1);
f2 = d1;
(d1->vtbl->xyz)(d1); /* this sets d1->b to 6 */
printf("d1->b is %d\n", d1->b);
(f2->vtbl->bar)(f2); /* this sets d1->b to 5, because it is invoke via
vtable */
printf("d1->b is %d\n", d1->b);
(f1->vtbl->bar)(f1); /* this sets f1->a to 3 */
printf("d1->a is %d\n", f1->a);

return 0;
}

----end program----

The problem w/ this approach is (a) its messy and error prone, and (b)
it only supports direct single-line inheritance. If you want to use
multiple inheritance or even mixin classes (abstract classes like java
interfaces), it gets much trickier, and (c) you have to do a LOT of writing.

Also, while we're on the topic you might check out my article on
closures in C, which relates very closely to what we're doing here:

http://www-128.ibm.com/developerwork...-highfunc.html

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017
Chris Hills
Guest
 
Posts: n/a
#9: Nov 14 '05

re: Port code from C++ to C?


In article <1116980947.994477.205040@g49g2000cwa.googlegroups .com>,
PengYu.UT@gmail.com <PengYu.UT@gmail.com> writes[color=blue]
>Hi,
>
>I have to use some machine with only support of C. But I have some C++
>programs, which use most C++ comman features. Is there any way to
>convert those C++ programs to C?
>
>Or is there any way that I can mimic C++ by C? So that even if I have
>to recode, I don't have to change the C++ code structures.
>
>Thanks!
>
>Best wishes,
>Peng
>[/color]

I Think this solves your problem: Comeau C++ compiler generates C as its
object code.

Comeau C/C++ 4.3.3: Watch for our Mac port
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries. Have you tried it?
comeau@comeaucomputing.com http://www.comeaucomputing.com

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
/\/\/ chris@phaedsys.org www.phaedsys.org \/\/\
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/



John Devereux
Guest
 
Posts: n/a
#10: Nov 14 '05

re: Port code from C++ to C?


"PengYu.UT@gmail.com" <PengYu.UT@gmail.com> writes:
[color=blue]
> I'm sorry that I cann't download this manual. It seems the above link
> is dead. If you have a copy would please email it to me as attachment.[/color]

My mail to you bounced with "illegal attachment" so I guess you are
stuck! I downloaded the file myself earlier today, but now the link
seems to be broken as you say. Perhaps it will work again soon!

--

John Devereux
PengYu.UT@gmail.com
Guest
 
Posts: n/a
#11: Nov 14 '05

re: Port code from C++ to C?


Thank you any way.

Peng

Roger Leigh
Guest
 
Posts: n/a
#12: Nov 14 '05

re: Port code from C++ to C?


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jonathan Bartlett <johnnyb@eskimo.com> writes:
[color=blue]
> To do OO in C, you usually do something like this:
>
> The C Version:
> --------------
> struct foo;
> struct vtable_foo
> {
> void (*bar)(struct foo*);
> void (*abc)(struct foo*);
> };[/color]
[color=blue]
> struct vtable_foo __vtable_foo;
> /* class initializer -- must be run EXACTLY ONCE before creating any
> instances of foo */
> void initialize_foo_class()
> {
> __vtable_foo.bar = foo_bar;
> __vtable_foo.abc = foo_abc;
> }
>
> /* constructor */
> void foo_initialize(struct foo *f)
> {
> f->vtbl = &__vtable_foo;
> f->a = 0;
> }
>
> struct doo;
> struct vtable_doo
> {
> void (*bar)(struct doo*);
> void (*abc)(struct doo*);
> void (*xyz)(struct doo*);
> };
> struct vtable_doo __vtable_doo;[/color]
[color=blue]
> void initialize_doo_class()
> {
> /* inherited from foo */
> __vtable_doo.bar = doo_bar; /* overriden in doo */
> __vtable_doo.abc = foo_abc;
>
> /* new in doo */
> __vtable_doo.xyz = doo_xyz;
> }
>
> void doo_initialize(struct doo *d)
> {
> d->vtbl = &__vtable_doo;
> d->a = 0;
> d->b = 0;
> }[/color]

The problem with this scheme is that your initialisers don't take a
vtable as a parameter. This prevents "chaining up" in inherited
vtables. You had to duplicate vtable_foo /by hand/ in vtable_doo.
This is messy, and won't scale: if you now alter vtable_foo, your code
is broken (you can't cast between the two types). What you really
want is:

typedef struct _FooClass
{
void (*bar)(struct foo*);
void (*abc)(struct foo*);
} FooClass;

typedef struct _DooClass
{
FooClass parent;
void (*xyz)(struct doo*);
} DooClass;

You can now freely cast between them, with no worries about a changing
API.
[color=blue]
> The problem w/ this approach is (a) its messy and error prone, and (b)
> it only supports direct single-line inheritance. If you want to use
> multiple inheritance or even mixin classes (abstract classes like java
> interfaces), it gets much trickier, and (c) you have to do a LOT of
> writing.[/color]

There are good libraries to help with this, such as GObject. They
handle interfaces, though multiple inheritance is asking too much (and
is of dubious value in any case).


Regards,
Roger

- --
Roger Leigh
Printing on GNU/Linux? http://gimp-print.sourceforge.net/
Debian GNU/Linux http://www.debian.org/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>

iD8DBQFClLorVcFcaSW/uEgRAolJAKDmSCdtuD9jitRBDdBPigTTC2XqBQCgvTAq
O4V8mnpDwi71CqDCaRX4FQo=
=eDbg
-----END PGP SIGNATURE-----
CBFalconer
Guest
 
Posts: n/a
#13: Nov 14 '05

re: Port code from C++ to C?


"PengYu.UT@gmail.com" wrote:[color=blue]
>
> I'm sorry that I cann't download this manual. It seems the above
> link is dead. If you have a copy would please email it to me as
> attachment. Thanks,[/color]

What manual? There is no link above, because you failed to quote
adequately. Who is 'you'? See my sig, below.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson


E. Robert Tisdale
Guest
 
Posts: n/a
#14: Nov 14 '05

re: Port code from C++ to C?


Jonathan Bartlett wrote:
[color=blue]
> To do OO in C, you usually do something like this:
> [snip][/color]
[color=blue]
> cat main.c[/color]
#include <stdio.h>

typedef struct foo {
const
void* vtbl;
int a;
} foo;

typedef struct vtable_foo {
void (*bar)(foo*);
void (*abc)(foo*);
} vtable_foo;

void actual_foo_bar(foo* p) {
p->a = 3;
}

inline /* virtual */
void foo_bar(foo* p) {
((vtable_foo*)(p->vtbl))->bar(p);
}

void actual_foo_abc(foo* p) {
p->a = 4;
}

inline /* virtual */
void foo_abc(foo* p) {
((vtable_foo*)(p->vtbl))->abc(p);
}

// [Unnecessary] class initializer --
// must be run EXACTLY ONCE
// need *never* be run.
// before creating any instances of foo
//void initialize_foo_class(void) {
// __vtable_foo.bar = foo_bar;
// __vtable_foo.abc = foo_abc;
// }

const
vtable_foo __vtable_foo = {actual_foo_bar,
actual_foo_abc};

// [No. This is not a] constructor.
// This is an initializer.
inline
void foo_initialize(foo *p) {
p->vtbl = (void*)(&__vtable_foo);
p->a = 0;
}

// This is a [pseudo] constructor.
inline
foo foo_create(void) {
foo f;
foo_initialize(&f);
return f;
}

// Always define a destructor
// even if it doesn't do anything.
inline
void foo_destroy(const foo* p) { }


//typedef struct doo {
// vtable_doo* vtbl;
// int a; // from foo
// int b;
// } doo;

typedef struct doo {
foo f;
int b;
} doo;

typedef struct vtable_doo {
void (*bar)(doo*);
void (*abc)(foo*);
void (*xyz)(doo*);
} vtable_doo;

void actual_doo_bar(doo* p) {
p->b = 5;
}

inline /* virtual */
void doo_bar(doo* p) {
((vtable_doo*)(p->f.vtbl))->bar(p);
}

inline /* virtual */
void doo_abc(doo* p) {
((vtable_doo*)(p->f.vtbl))->abc((foo*)p);
}

void actual_doo_xyz(doo* p) {
p->b = 6;
}

inline /* virtual */
void doo_xyz(doo* p) {
((vtable_doo*)(p->f.vtbl))->xyz(p);
}

// Unnecessary "class" initializer.
//void initialize_doo_class(void) {
// // inherited from foo
// __vtable_doo.bar = doo_bar; /* overriden in doo */
// __vtable_doo.abc = foo_abc;
//
// // new in doo
// __vtable_doo.xyz = doo_xyz;
// }

const
vtable_doo __vtable_doo = {actual_doo_bar,
actual_foo_abc,
actual_doo_xyz};

// This is an initializer.
inline
void doo_initialize(doo* p) {
p->f.vtbl = (void*)(&__vtable_doo);
p->f.a = 0;
p->b = 0;
}

// This is a [pseudo] constructor.
inline
doo doo_create(void) {
doo d;
doo_initialize(&d);
return d;
}

// Always define a destructor
// even if it doesn't do anything.
inline
void doo_destroy(const doo* p) { }

int main(int argc, char* argv[]) {
doo d1 = doo_create();
foo f1 = foo_create();
foo* p = &(d1.f);

doo_xyz(&d1); // This sets d1.b to 6.
printf("d1.b is %d\n", d1.b);

foo_bar(p); // This sets d1.b to 5
// because it is invoked via vtable.
printf("d1.b is %d\n", d1.b);

foo_bar(&f1); // This sets f1.a to 3.
printf("f1.a is %d\n", f1.a);

foo_destroy(&f1); // Always call the destructors
doo_destroy(&d1); // even if they don't do anything.

return 0;
}
[color=blue]
> gcc -Wall -std=c99 -pedantic -o main main.c
> ./main[/color]
d1.b is 6
d1.b is 5
f1.a is 3
Closed Thread