FAQ 13.8, comparing strings

Discussion in 'C Programming' started by vippstar@gmail.com, Apr 28, 2008.

  1. Guest

    On Apr 28, 7:00 pm, arnuld <> wrote:
    > > On Mon, 28 Apr 2008 07:25:53 +0000, Richard Heathfield wrote:
    > > #include <string.h>
    > > int p_strcmp(const void *pv1, const void *pv2)
    > > {
    > > char * const * v1 = pv1;
    > > char * const * v2 = pv2;
    > > return strcmp(*v1, *v2);
    > > }

    >
    > Either you are not understanding me or I am not able to understand this
    > <p_strcmp> thing. This is your code:
    >
    > compare these 2 paragraphs:
    >
    > In theory, you get a <pointer to const void> and you use it to initialize
    > a <pointer to a const pointer to char> . In practice, you get a <pointer
    > to a pointer to char> and you are using it to initialize a <pointer to a
    > const pointer to char> and then dereference it to a <const pointer to
    > char>.
    >
    > Because you already know that the input argument will be <char**> so we

    /You/ do know that. The compiler doesn't. In your code you dereference
    a void * pointer and then use its value, which is not possible in ISO
    C.
    > can simply dereference it and get a <char*> which could be used for

    How do you get a char * if you dereference a void *?
    > <strcmp> since <strcmp> does not require a <const pointer>. Hence It
    > could be simply this:
    >
    > int p_strcmp(const void *pv1, const void *pv2)
    > {
    > return strcmp(*pv1, *pv2);

    Here, you dereference a void pointer as I said before. This void *
    pointer is given the value of a char ** pointer. That's why RH assigns
    it to such pointer, and then dereferences it. Consider this:

    #include <stdio.h>
    int f(void *p);
    int main(void) {
    int i = 10;
    int *k = &i;
    printf("%d\n", f(&k)); // pass address of int *, type is int **
    return 0;
    }
    int f(void *p) {
    int **i = p; // p points to an int **
    return **i + 10;
    }

    It's the same thing.

    P.S. Your signature appeared twice.
    , Apr 28, 2008
    #1
    1. Advertising

  2. santosh Guest

    arnuld wrote:

    <snip>

    > Now I got it. <void*> is a compile-time phenomenon which , actually,
    > helps a lot as run-time phenomenon because in many cases we could
    > know the types only at run-time.


    <snip>

    Can you clarify this? What do you mean by "compile-time phenomenon"
    and "run-time phenomenon"?
    santosh, Apr 28, 2008
    #2
    1. Advertising

  3. arnuld Guest

    > On Mon, 28 Apr 2008 07:25:53 +0000, Richard Heathfield wrote:


    > #include <string.h>
    > int p_strcmp(const void *pv1, const void *pv2)
    > {
    > char * const * v1 = pv1;
    > char * const * v2 = pv2;
    > return strcmp(*v1, *v2);
    > }



    Either you are not understanding me or I am not able to understand this
    <p_strcmp> thing. This is your code:



    compare these 2 paragraphs:

    In theory, you get a <pointer to const void> and you use it to initialize
    a <pointer to a const pointer to char> . In practice, you get a <pointer
    to a pointer to char> and you are using it to initialize a <pointer to a
    const pointer to char> and then dereference it to a <const pointer to
    char>.


    Because you already know that the input argument will be <char**> so we
    can simply dereference it and get a <char*> which could be used for
    <strcmp> since <strcmp> does not require a <const pointer>. Hence It
    could be simply this:


    int p_strcmp(const void *pv1, const void *pv2)
    {
    return strcmp(*pv1, *pv2);
    }


    I need explanation on this as it<p_strcmp> code is biting me
    from the very 1st day I saw it in section 13.8 of the FAQ and I still
    can't seem to comprehend the WHY of it.





    --
    http://lispmachine.wordpress.com/
    my email ID is at the above address


    --
    http://lispmachine.wordpress.com/
    my email ID is at the above address
    arnuld, Apr 28, 2008
    #3
  4. arnuld Guest

    > On Mon, 28 Apr 2008 04:11:11 -0700, vippstar wrote:

    > #include <stdio.h>
    > int f(void *p);
    > int main(void) {
    > int i = 10;
    > int *k = &i;
    > printf("%d\n", f(&k)); // pass address of int *, type is int **
    > return 0;
    > }
    > int f(void *p) {
    > int **i = p; // p points to an int **
    > return **i + 10;
    > }
    >
    > It's the same thing.


    O...K..A..Y....

    Now I got it. <void*> is a compile-time phenomenon which , actually,
    helps a lot as run-time phenomenon because in many cases we could know
    the types only at run-time.


    Right ?


    still one questions remains:


    #include <string.h>
    int p_strcmp(const void *pv1, const void *pv2)
    {
    char * const * v1 = pv1;
    char * const * v2 = pv2;
    return strcmp(*v1, *v2);
    }


    I can use <char** v1 = pv1> or <const char** v1 = pv1>

    why use <char *const *v1 = pv1> ?




    --
    http://lispmachine.wordpress.com/
    my email ID is at the above address
    arnuld, Apr 28, 2008
    #4
  5. santosh wrote:
    > arnuld wrote:
    > > Now I got it. <void*> is a compile-time phenomenon which,
    > > actually, helps a lot as run-time phenomenon because in
    > > many cases we could know the types only at run-time.

    >
    > <snip>
    >
    > Can you clarify this? What do you mean by "compile-time
    > phenomenon" and "run-time phenomenon"?


    Sounds like the OP is drawing the distinction between object
    type, which is known at compile time since C is statically
    typed, and an object's effective type which need only be
    known at runtime.

    --
    Peter
    Peter Nilsson, Apr 28, 2008
    #5
  6. arnuld wrote:
    > int p_strcmp(const void *pv1, const void *pv2)
    > {
    > char * const * v1 = pv1;
    > char * const * v2 = pv2;
    > return strcmp(*v1, *v2);
    > }
    >
    >
    > I can use <char** v1 = pv1> or <const char** v1 = pv1>
    >
    > why use <char *const *v1 = pv1> ?


    The const or volatile qualifier applies to the left, with the exception of
    when it is at the leftmost part of a declaration, then it applies to the
    right. For consistency, I would therefore suggest that you drop the habit
    of writing things like this:

    const char* p;

    in favour of this:

    char const* p;

    Now, you can read this from right to left, i.e. 'p' is a pointer to a
    constant 'char'. Getting back to the above example, you then have

    const void *pv1

    which I would rather write as

    void const* pv1

    Then, you simply replace the placeholder type 'void' with the real type of
    the array (I guess it's about sorting with qsort()), and that is 'char*'
    (note: without any const!):

    char* const* pv1

    This then reads 'pv1' is a pointer to a const pointer to a 'char'. This
    basically means that you can not redirect the pointer to anywhere else,
    i.e. an expression like this will fail to compile:

    *pv1 = "foo";

    Note that I personally would have added another const:

    char const* const* pv1

    This then also prevents accidental modification of the string it points to,
    but for the general principle of converting between typed and typeless
    pointers and back this isn't necessary.


    BTW:
    Some really paranoid people would even have added another const there:

    char const* const* const pv1

    I wouldn't do so here, but in general it helps in other situations like
    this:

    float const pi2 = acosf(0.0f);
    ... // LOTS of code
    ... // use pi2 here

    The point is that from the declaration you already _know_ that pi2 isn't
    changed anywhere in between. Not only that, even if you tried to change it
    accidentally, you would get a compiler error. The problem with this is that
    many C compilers don't allow you (according to C89) to define variables in
    the middle of a block, only at the beginning.

    cheers

    Uli
    Ulrich Eckhardt, Apr 29, 2008
    #6
  7. arnuld Guest

    > On Mon, 28 Apr 2008 17:44:53 +0530, santosh wrote:

    > Can you clarify this? What do you mean by "compile-time phenomenon"
    > and "run-time phenomenon"?



    of course :) . This is just what I came to think of about types in C. If
    am wrong, poke me in the eye ;)



    <void*> points to no type, practically.

    Lets us say that a C program asks the user for input, I can not enter some
    words at standard input and make them of type <void>, they can be stored
    in <array of char> but not in <array of void>. Section 13.8 of FAQ has a
    function for comparing strings called <p_strcmp> which compiles fine
    and takes 2 <const void*> as arguments. At run-time, for example, either
    a <char*> or even a <char**> can be given as input and <void*> will
    handle them gracefully but I can not give a <void*> to it as argument at
    run-time. The input has to be of some type, to be useful to be processed
    by the program.


    Hence, <void> type exists at compile-time for the kind of input we do not
    know the type of yet but at run-time I can not make any input as of
    <void> type.



    --
    http://lispmachine.wordpress.com/
    my email ID is at the above address
    arnuld, Apr 29, 2008
    #7
    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. kaeli
    Replies:
    8
    Views:
    588
    Chris Smith
    Nov 18, 2004
  2. HS1

    Comparing two strings

    HS1, Nov 28, 2004, in forum: Java
    Replies:
    3
    Views:
    453
    Rob van der Leek
    Nov 29, 2004
  3. manzur

    comparing strings

    manzur, Mar 7, 2006, in forum: Java
    Replies:
    8
    Views:
    382
    Roedy Green
    Mar 7, 2006
  4. Rick

    Comparing strings from within strings

    Rick, Oct 21, 2003, in forum: C Programming
    Replies:
    3
    Views:
    375
    Irrwahn Grausewitz
    Oct 21, 2003
  5. Ben

    Strings, Strings and Damned Strings

    Ben, Jun 22, 2006, in forum: C Programming
    Replies:
    14
    Views:
    754
    Malcolm
    Jun 24, 2006
Loading...

Share This Page