CCL vs STL: a comparison

Discussion in 'C Programming' started by jacob navia, May 11, 2012.

  1. jacob navia

    jacob navia Guest

    Here is a comparison of two source codes that use the C++ STL and the
    C containers library (ccl).

    First, the C++ example:

    // Standard Template Library example

    #include <iostream>
    #include <list>
    using namespace std;

    // Simple example uses type int

    int main(void)
    {
    list<int> L;
    L.push_back(0); // Insert a new element at the end
    L.push_front(0); // Insert a new element at the beginning
    L.insert(++L.begin(),2);// Insert "2" before position of first argument
    // (Place before second argument)
    L.push_back(5);
    L.push_back(6);

    list<int>::iterator i;

    for(i=L.begin(); i != L.end(); ++i) cout << *i << " ";
    cout << endl;
    return 0;
    }

    /* OUTPUT: 0 2 0 5 6 */
    ---------------------------------------------------------------------------
    Here is the C example
    #include "containers.h"
    static int PrintInt(void *pdata,void *extraArgs)
    {
    int i = *(int *)pdata;
    fprintf(extraArgs,"%d ",i);
    }
    int main(void)
    {
    List *L;
    int data;

    L = iList.Create(sizeof(int));

    data = 0;
    iList.Add(L,&data);
    iList.PushFront(L,&data);
    data = 2;
    iList.InsertAt(L,1,&data);
    data = 5;
    iList.Add(L,&data);
    data = 6;
    iList.Add(L,&data);
    iList.Apply(L,PrintInt,stdout);
    iList.Finalize(L);
    }
    ----------------------------------------------------------------------------

    I could have used iterators to print the list but I think using "Apply"
    looks better ...

    What do you think?
     
    jacob navia, May 11, 2012
    #1
    1. Advertising

  2. jacob navia

    Ike Naar Guest

    On 2012-05-11, jacob navia <> wrote:
    > #include "containers.h"
    > static int PrintInt(void *pdata,void *extraArgs)
    > {
    > int i = *(int *)pdata;
    > fprintf(extraArgs,"%d ",i);
    > }


    PrintInt promises to return an int, but it doesn't.

    > int main(void)
    > {
    > List *L;
    > int data;
    >
    > L = iList.Create(sizeof(int));
    >
    > data = 0;
    > iList.Add(L,&data);
    > iList.PushFront(L,&data);
    > data = 2;
    > iList.InsertAt(L,1,&data);
    > data = 5;
    > iList.Add(L,&data);
    > data = 6;
    > iList.Add(L,&data);
    > iList.Apply(L,PrintInt,stdout);


    No terminating newline is printed?

    > iList.Finalize(L);
    > }


    This

    int data = 5;
    iList.Add(L, &data);

    looks clumsier than

    L.push_back(5);

    and it's more prone to errors,
    for instance, the compiler will accept

    long data = 5;
    iList.Add(L, &data);

    but this may lead to unexpected run-time behaviour on
    a machine on which sizeof(int) != sizeof(long)..
     
    Ike Naar, May 11, 2012
    #2
    1. Advertising

  3. jacob navia

    jacob navia Guest

    Le 11/05/12 19:54, Ike Naar a écrit :
    > On 2012-05-11, jacob navia<> wrote:
    >> #include "containers.h"
    >> static int PrintInt(void *pdata,void *extraArgs)
    >> {
    >> int i = *(int *)pdata;
    >> fprintf(extraArgs,"%d ",i);
    >> }

    >
    > PrintInt promises to return an int, but it doesn't.
    >



    Yes, this is an error. Should return one or other value.

    >> int main(void)
    >> {
    >> List *L;
    >> int data;
    >>
    >> L = iList.Create(sizeof(int));
    >>
    >> data = 0;
    >> iList.Add(L,&data);
    >> iList.PushFront(L,&data);
    >> data = 2;
    >> iList.InsertAt(L,1,&data);
    >> data = 5;
    >> iList.Add(L,&data);
    >> data = 6;
    >> iList.Add(L,&data);
    >> iList.Apply(L,PrintInt,stdout);

    >
    > No terminating newline is printed?
    >


    No. But it is easy to add one.

    >> iList.Finalize(L);
    >> }

    >
    > This
    >
    > int data = 5;
    > iList.Add(L,&data);
    >
    > looks clumsier than
    >
    > L.push_back(5);
    >
    > and it's more prone to errors,
    > for instance, the compiler will accept
    >
    > long data = 5;
    > iList.Add(L,&data);
    >
    > but this may lead to unexpected run-time behaviour on
    > a machine on which sizeof(int) != sizeof(long)..


    Yes, you can put any value, and you have to keep track of what you are
    doing.

    A specific interface for a specific data type can be obtained by using
    the template file furnished with the sample implementation.

    If you do that you obtain compiler checking at compile time.
     
    jacob navia, May 11, 2012
    #3
  4. jacob navia <> writes:

    > Here is a comparison of two source codes that use the C++ STL and the
    > C containers library (ccl).


    It's not clear what the point is. In terms of code clarity and
    simplicity, C++ is likely to come out on top in simple comparisons like
    this.

    > First, the C++ example:
    >
    > // Standard Template Library example
    >
    > #include <iostream>
    > #include <list>
    > using namespace std;
    >
    > // Simple example uses type int
    >
    > int main(void)
    > {
    > list<int> L;


    You can also just initialise the list:

    list<int> L = {0, 2, 0, 5, 6};

    C libraries will always have live withing C's core language limitations.

    > L.push_back(0); // Insert a new element at the end
    > L.push_front(0); // Insert a new element at the beginning
    > L.insert(++L.begin(),2);// Insert "2" before position of first argument
    > // (Place before second argument)
    > L.push_back(5);
    > L.push_back(6);
    >
    > list<int>::iterator i;
    >
    > for(i=L.begin(); i != L.end(); ++i) cout << *i << " ";


    Modern C++ has this:

    for (int i: L) cout << i << " ";

    Nice, yes?

    > cout << endl;
    > return 0;
    > }
    >
    > /* OUTPUT: 0 2 0 5 6 */
    > ---------------------------------------------------------------------------
    > Here is the C example
    > #include "containers.h"
    > static int PrintInt(void *pdata,void *extraArgs)
    > {
    > int i = *(int *)pdata;
    > fprintf(extraArgs,"%d ",i);
    > }
    > int main(void)
    > {
    > List *L;
    > int data;
    >
    > L = iList.Create(sizeof(int));
    >
    > data = 0;
    > iList.Add(L,&data);
    > iList.PushFront(L,&data);
    > data = 2;
    > iList.InsertAt(L,1,&data);
    > data = 5;
    > iList.Add(L,&data);
    > data = 6;
    > iList.Add(L,&data);
    > iList.Apply(L,PrintInt,stdout);
    > iList.Finalize(L);
    > }
    > ----------------------------------------------------------------------------
    >
    > I could have used iterators to print the list but I think using "Apply"
    > looks better ...


    C++ also has an "apply" and, what's more, it doesn't need a top-level
    function definition:

    for_each(L.begin(), L.end(), [](int i){ cout << i << " "; });

    > What do you think?


    I am not sure what you are really asking.

    --
    Ben.
     
    Ben Bacarisse, May 11, 2012
    #4
  5. jacob navia

    jacob navia Guest

    Le 11/05/12 21:31, Ben Bacarisse a écrit :
    >
    > You can also just initialise the list:
    >
    > list<int> L = {0, 2, 0, 5, 6};



    In the C library you can do the equivalent with


    int tab[]={0, 2, 0, 5, 6};

    iList.InitializeWith(sizeof(int),5,tab);
     
    jacob navia, May 11, 2012
    #5
  6. jacob navia

    jacob navia Guest

    Le 11/05/12 21:31, Ben Bacarisse a écrit :
    > for (int i: L) cout<< i<< " ";


    I added this:

    #if 0
    for(i=L.begin(); i != L.end(); ++i) cout << *i << " ";
    cout << endl;
    #else
    for (int i: L) cout << i << " ";
    #endif

    and obtained:

    ~ $ g++ list.cpp
    list.cpp: In function ‘int main()’:
    list.cpp:25: error: a function-definition is not allowed here before ‘:’
    token
    list.cpp:27: error: expected primary-expression before ‘return’
    list.cpp:27: error: expected `;' before ‘return’
    list.cpp:27: error: expected primary-expression before ‘return’
    list.cpp:27: error: expected `)' before ‘return’
     
    jacob navia, May 11, 2012
    #6
  7. jacob navia <> writes:

    > Le 11/05/12 21:31, Ben Bacarisse a écrit :
    >>
    >> You can also just initialise the list:
    >>
    >> list<int> L = {0, 2, 0, 5, 6};

    >
    >
    > In the C library you can do the equivalent with
    >
    >
    > int tab[]={0, 2, 0, 5, 6};
    >
    > iList.InitializeWith(sizeof(int),5,tab);


    The 5 is unfortunate. Did you consider

    iList.InitializeWith(sizeof *tab, sizeof tab, tab);

    ?

    --
    Ben.
     
    Ben Bacarisse, May 11, 2012
    #7
  8. jacob navia

    jacob navia Guest

    Le 11/05/12 21:31, Ben Bacarisse a écrit :
    > for_each(L.begin(), L.end(), [](int i){ cout<< i<< " "; });


    I added this:
    for_each(L.begin(), L.end(), [](int i){ cout << i << " "; });

    as you wrote and obtained:

    list.cpp:26: error: expected primary-expression before ‘[’ token
    list.cpp:26: error: expected primary-expression before ‘]’ token
    list.cpp:26: error: expected primary-expression before ‘int’

    ~$ g++ -v
    Using built-in specs.
    Target: i686-apple-darwin11
    Configured with:
    /private/var/tmp/llvmgcc42/llvmgcc42-2336.9~22/src/configure
    --disable-checking --enable-werror
    --prefix=/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2
    --mandir=/share/man --enable-languages=c,objc,c++,obj-c++
    --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/
    --with-slibdir=/usr/lib --build=i686-apple-darwin11
    --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2336.9~22/dst-llvmCore/Developer/usr/local
    --program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11
    --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/4.2.1
    Thread model: posix
    gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00)
     
    jacob navia, May 11, 2012
    #8
  9. jacob navia

    jacob navia Guest

    Le 11/05/12 21:31, Ben Bacarisse a écrit :
    > I am not sure what you are really asking.


    Just trying to discuss the two approaches. I am sure
    C++ has more "syntactic sugar" than C, but the
    two approaches lead to similar code.

    I was just asking from feedback about that, maybe improvements
    proposals.
     
    jacob navia, May 11, 2012
    #9
  10. jacob navia <> writes:

    > Le 11/05/12 21:31, Ben Bacarisse a écrit :
    >> for (int i: L) cout<< i<< " ";

    >
    > I added this:
    >
    > #if 0
    > for(i=L.begin(); i != L.end(); ++i) cout << *i << " ";
    > cout << endl;
    > #else
    > for (int i: L) cout << i << " ";
    > #endif
    >
    > and obtained:
    >
    > ~ $ g++ list.cpp
    > list.cpp: In function ‘int main()’:
    > list.cpp:25: error: a function-definition is not allowed here before
    > ‘:’ token
    > list.cpp:27: error: expected primary-expression before ‘return’
    > list.cpp:27: error: expected `;' before ‘return’
    > list.cpp:27: error: expected primary-expression before ‘return’
    > list.cpp:27: error: expected `)' before ‘return’


    Surely that's a question (if it is a question) for comp.lang.c++? But
    since I "opened the door" as they say in cheap TV legal dramas -- it's a
    new feature, but recent g++ compilers have it (-std=c++0x).

    --
    Ben.
     
    Ben Bacarisse, May 11, 2012
    #10
  11. jacob navia <> writes:

    > Le 11/05/12 21:31, Ben Bacarisse a écrit :
    >> for_each(L.begin(), L.end(), [](int i){ cout<< i<< " "; });

    >
    > I added this:
    > for_each(L.begin(), L.end(), [](int i){ cout << i << " "; });
    >
    > as you wrote and obtained:


    <snip errors>

    It's valid C++, but surely this is not the place to discuss C++ errors?

    --
    Ben.
     
    Ben Bacarisse, May 11, 2012
    #11
  12. jacob navia

    jacob navia Guest

    Le 11/05/12 22:02, Ben Bacarisse a écrit :
    > jacob navia<> writes:
    >
    >> Le 11/05/12 21:31, Ben Bacarisse a écrit :
    >>>
    >>> You can also just initialise the list:
    >>>
    >>> list<int> L = {0, 2, 0, 5, 6};

    >>
    >>
    >> In the C library you can do the equivalent with
    >>
    >>
    >> int tab[]={0, 2, 0, 5, 6};
    >>
    >> iList.InitializeWith(sizeof(int),5,tab);

    >
    > The 5 is unfortunate. Did you consider
    >
    > iList.InitializeWith(sizeof *tab, sizeof tab, tab);
    >
    > ?
    >


    The prototype is:
    List *InitializeWith(size_t elementSize, size_t n, const void *Data);

    You would propose then:
    List *InitializeWith(size_t elementSize, size_t datasize, const
    void *Data);

    where datasize would be the total size of the table, that should be a
    multiple of elementSize?

    I wote the 5 to be short. Normally I have a
    #define SIZEOF(tab) (sizeof(tab)/sizeof(tab[0])
    macro somewhere
     
    jacob navia, May 11, 2012
    #12
  13. jacob navia

    jacob navia Guest

    Le 11/05/12 22:11, Ben Bacarisse a écrit :
    > It's valid C++, but surely this is not the place to discuss C++ errors?


    Why not? If we are comparing C with C++ code it is ok.

    Or did I made a transcription error?
     
    jacob navia, May 11, 2012
    #13
  14. jacob navia

    Guest

    On Friday, May 11, 2012 3:15:15 PM UTC-5, jacob navia wrote:
    > Le 11/05/12 22:11, Ben Bacarisse a écrit :
    > > It's valid C++, but surely this is not the place to discuss C++ errors?

    >
    > Why not? If we are comparing C with C++ code it is ok.
    >
    > Or did I made a transcription error?


    The code is valid C++, but makes use of C++11 features which your compiler does not support.
     
    , May 11, 2012
    #14
  15. jacob navia <> writes:

    > Le 11/05/12 22:02, Ben Bacarisse a écrit :
    >> jacob navia<> writes:
    >>
    >>> Le 11/05/12 21:31, Ben Bacarisse a écrit :
    >>>>
    >>>> You can also just initialise the list:
    >>>>
    >>>> list<int> L = {0, 2, 0, 5, 6};
    >>>
    >>>
    >>> In the C library you can do the equivalent with
    >>>
    >>>
    >>> int tab[]={0, 2, 0, 5, 6};
    >>>
    >>> iList.InitializeWith(sizeof(int),5,tab);

    >>
    >> The 5 is unfortunate. Did you consider
    >>
    >> iList.InitializeWith(sizeof *tab, sizeof tab, tab);
    >>
    >> ?
    >>

    >
    > The prototype is:
    > List *InitializeWith(size_t elementSize, size_t n, const void *Data);
    >
    > You would propose then:
    > List *InitializeWith(size_t elementSize, size_t datasize, const
    > void *Data);
    >
    > where datasize would be the total size of the table, that should be a
    > multiple of elementSize?


    Yes.

    > I wote the 5 to be short. Normally I have a
    > #define SIZEOF(tab) (sizeof(tab)/sizeof(tab[0])
    > macro somewhere


    It all depends on how you think InitializeWith will be used. How often
    will the number of elements be more easily available than the number of
    bytes? Even if the answer is "almost always", n * sizeof *tab is
    simpler that sizeof(tab)/sizeof(tab[0]).

    --
    Ben.
     
    Ben Bacarisse, May 11, 2012
    #15
  16. jacob navia

    Ian Collins Guest

    On 05/12/12 08:06 AM, jacob navia wrote:
    > Le 11/05/12 21:31, Ben Bacarisse a écrit :
    >> I am not sure what you are really asking.

    >
    > Just trying to discuss the two approaches. I am sure
    > C++ has more "syntactic sugar" than C, but the
    > two approaches lead to similar code.


    Not really. As Ben demonstrated, the "syntactic sugar" leads to much
    more concise and less error prone code. In this case, 2 lines rather
    than 18!

    > I was just asking from feedback about that, maybe improvements
    > proposals.


    What you have is probably the best that can be done within the confines
    of C.

    --
    Ian Collins
     
    Ian Collins, May 11, 2012
    #16
  17. jacob navia

    BartC Guest

    "jacob navia" <> wrote in message
    news:jojghh$91l$...
    > Here is a comparison of two source codes that use the C++ STL and the
    > C containers library (ccl).


    > List *L;
    > int data;
    >
    > L = iList.Create(sizeof(int));
    >
    > data = 0;
    > iList.Add(L,&data);


    Shame you can't use immediate data. Then that line becomes:

    ilist.Add(L,0);

    Although it might not be much trouble (*in this simple case*) to do:

    ilist.Add(L,imm(0));

    where imm is "int* imm(int)".

    But perhaps in actual use, immediate data isn't used so much.

    --
    Barts
     
    BartC, May 11, 2012
    #17
  18. "BartC" <> writes:

    > "jacob navia" <> wrote in message
    > news:jojghh$91l$...
    >> Here is a comparison of two source codes that use the C++ STL and the
    >> C containers library (ccl).

    >
    >> List *L;
    >> int data;
    >>
    >> L = iList.Create(sizeof(int));
    >>
    >> data = 0;
    >> iList.Add(L,&data);

    >
    > Shame you can't use immediate data. Then that line becomes:
    >
    > ilist.Add(L,0);


    C++ has compound literals which produce lvalues so you can apply & to
    the result:

    ilist.Add(L, &(int){0});

    <snip>
    --
    Ben.
     
    Ben Bacarisse, May 12, 2012
    #18
  19. Ben Bacarisse <> writes:

    > "BartC" <> writes:
    >
    >> "jacob navia" <> wrote in message
    >> news:jojghh$91l$...
    >>> Here is a comparison of two source codes that use the C++ STL and the
    >>> C containers library (ccl).

    >>
    >>> List *L;
    >>> int data;
    >>>
    >>> L = iList.Create(sizeof(int));
    >>>
    >>> data = 0;
    >>> iList.Add(L,&data);

    >>
    >> Shame you can't use immediate data. Then that line becomes:
    >>
    >> ilist.Add(L,0);

    >
    > C++ has compound literals which produce lvalues so you can apply & to


    <slap!> C99, of course, not C++.

    > the result:
    >
    > ilist.Add(L, &(int){0});
    >
    > <snip>


    --
    Ben.
     
    Ben Bacarisse, May 12, 2012
    #19
  20. jacob navia

    Tim Rentsch Guest

    Ben Bacarisse <> writes:

    > Ben Bacarisse <> writes:
    >
    >> "BartC" <> writes:
    >>
    >>> "jacob navia" <> wrote in message
    >>> news:jojghh$91l$...
    >>>> Here is a comparison of two source codes that use the C++ STL and the
    >>>> C containers library (ccl).
    >>>
    >>>> List *L;
    >>>> int data;
    >>>>
    >>>> L = iList.Create(sizeof(int));
    >>>>
    >>>> data = 0;
    >>>> iList.Add(L,&data);
    >>>
    >>> Shame you can't use immediate data. Then that line becomes:
    >>>
    >>> ilist.Add(L,0);

    >>
    >> C++ has compound literals which produce lvalues so you can apply & to

    >
    > <slap!> C99, of course, not C++.


    C99, C11, C++ - they're all about the same. :)
     
    Tim Rentsch, May 12, 2012
    #20
    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. jacob navia

    New release of the C Containers Library (CCL)

    jacob navia, Oct 30, 2010, in forum: C Programming
    Replies:
    117
    Views:
    2,013
  2. Jon
    Replies:
    16
    Views:
    564
  3. jacob navia

    ccl and stl: design differences

    jacob navia, Apr 17, 2011, in forum: C Programming
    Replies:
    0
    Views:
    205
    jacob navia
    Apr 17, 2011
  4. HENRY Eshbaugh

    Re: ccl

    HENRY Eshbaugh, Aug 29, 2011, in forum: C Programming
    Replies:
    3
    Views:
    304
    HENRY Eshbaugh
    Aug 30, 2011
  5. jacob navia

    Updates to the ccl

    jacob navia, Jun 7, 2012, in forum: C Programming
    Replies:
    35
    Views:
    1,060
    Malcolm McLean
    Jul 7, 2012
Loading...

Share This Page