Port code from C++ to C?

Discussion in 'C Programming' started by PengYu.UT@gmail.com, May 25, 2005.

  1. Guest

    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
     
    , May 25, 2005
    #1
    1. Advertising

  2. In article <>,
    <> wrote:
    >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?


    Please see the thread starting from
    http://groups.google.ca/group/comp.lang.c/msg/ff592bd669995492
    --
    "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
     
    Walter Roberson, May 25, 2005
    #2
    1. Advertising

  3. Guest

    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
     
    , May 25, 2005
    #3
  4. In article <>,
    <> wrote:
    >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.


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


    >So the problem right now is that how to implement OO in C language.


    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
     
    Walter Roberson, May 25, 2005
    #4
  5. gooch Guest

    wrote:
    > 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


    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.
     
    gooch, May 25, 2005
    #5
  6. "" <> writes:

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


    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
     
    John Devereux, May 25, 2005
    #6
  7. Guest

    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
     
    , May 25, 2005
    #7
  8. 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/developerworks/linux/library/l-highfunc.html

    Jon
    ----
    Learn to program using Linux assembly language
    http://www.cafeshops.com/bartlettpublish.8640017
     
    Jonathan Bartlett, May 25, 2005
    #8
  9. Chris Hills Guest

    In article <>,
    <> writes
    >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
    >


    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?
    http://www.comeaucomputing.com

    --
    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
    \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
    /\/\/ www.phaedsys.org \/\/\
    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
     
    Chris Hills, May 25, 2005
    #9
  10. "" <> writes:

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


    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
     
    John Devereux, May 25, 2005
    #10
  11. Guest

    Thank you any way.

    Peng
     
    , May 25, 2005
    #11
  12. Roger Leigh Guest

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

    Jonathan Bartlett <> writes:

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


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


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


    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.

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


    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-----
     
    Roger Leigh, May 25, 2005
    #12
  13. Jonathan Bartlett wrote:

    > To do OO in C, you usually do something like this:
    > [snip]


    > cat main.c

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

    > gcc -Wall -std=c99 -pedantic -o main main.c
    > ./main

    d1.b is 6
    d1.b is 5
    f1.a is 3
     
    E. Robert Tisdale, May 25, 2005
    #13
  14. CBFalconer Guest

    "" wrote:
    >
    > 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,


    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
     
    CBFalconer, May 25, 2005
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John T. Goodman

    Overhead of 4-port over 2-port SRAM

    John T. Goodman, Jan 25, 2005, in forum: VHDL
    Replies:
    0
    Views:
    609
    John T. Goodman
    Jan 25, 2005
  2. Sean Wolfe
    Replies:
    1
    Views:
    2,263
    Joerg Jooss
    Apr 28, 2005
  3. b3ny
    Replies:
    11
    Views:
    929
    Babu Kalakrishnan
    Nov 20, 2004
  4. Gerald Klix
    Replies:
    0
    Views:
    1,278
    Gerald Klix
    Oct 26, 2005
  5. Pom
    Replies:
    2
    Views:
    1,679
    Bas-i
    Jan 31, 2007
Loading...

Share This Page