Is char** (or char*[]) implicitly convertible to 'const char * const *'?

Discussion in 'C Programming' started by kevin.hall@motioneng.com, Oct 28, 2005.

  1. Guest

    Is char** (or char*[]) implicitly convertible to 'const char * const
    *'?

    I couldn't find anything about it in the standard. MSVS 8.0 allows
    this. I'm curious if I'll run into trouble with other compilers like
    GCC though.

    Many thanks!

    - Kevin
     
    , Oct 28, 2005
    #1
    1. Advertising

  2. Skarmander Guest

    Re: Is char** (or char*[]) implicitly convertible to 'const char* const *'?

    wrote:
    > Is char** (or char*[]) implicitly convertible to 'const char * const
    > *'?
    >


    You put this in parentheses like they're equal types. They're not.

    > I couldn't find anything about it in the standard. MSVS 8.0 allows
    > this. I'm curious if I'll run into trouble with other compilers like
    > GCC though.
    >


    The answer is no, these implicit conversions are not allowed. An
    explicit cast is required. From the FAQ:
    http://www.eskimo.com/~scs/C-faq/q11.10.html.

    When you try this with gcc, it will issue a warning regardless of
    dialect settings. Other compilers might make it an error.

    S.
     
    Skarmander, Oct 28, 2005
    #2
    1. Advertising

  3. Guest

    Skarmander, thank you for your response. I do appreciate it.

    I know they aren't equal types -- although char*[] is implicitly
    convertible to char** (but obviously not the other way around).

    I did verify with Comeau's online compiler that C in strict mode will
    not allow the conversion (the non-strict mode is tolerant of the
    conversion). However, Comeau's C++ compiler in strict mode does allow
    the conversion.

    Is C++ really more lenient in this respect? (no response required. I
    know that if I want an answer I'll have to first search the C++
    standard then post in comp.lang.c++ if I'm lost).

    It's unfortunate that C is so strict about this. I really strive to be
    const-correct in my code, and if my function is going to take 'char**'
    argument but not modify it, then it seems prudent to indicate this with
    'const char * const *'. But expecting other people to cast is even
    more undesirable.

    Does anyone know why C is so strict in this area? Is this something
    that could be safely less-strict?

    Thanks again!

    - Kevin
     
    , Oct 29, 2005
    #3
  4. Jordan Abel Guest

    On 2005-10-28, Skarmander <> wrote:
    > wrote:
    >> Is char** (or char*[]) implicitly convertible to 'const char * const
    >> *'?
    >>

    >
    > You put this in parentheses like they're equal types. They're not.


    No, but char*[] is implicitly convertable to char **.

    >> I couldn't find anything about it in the standard. MSVS 8.0 allows
    >> this. I'm curious if I'll run into trouble with other compilers like
    >> GCC though.
    >>

    >
    > The answer is no, these implicit conversions are not allowed. An
    > explicit cast is required. From the FAQ:
    > http://www.eskimo.com/~scs/C-faq/q11.10.html.


    I'd like to know the justification for this. Is there or might there
    be a system on which const pointers have a different representation
    than non-const ones?

    You (and that FAQ) seem to think that a cast would work, and would
    not cause undefined behavior, which makes me think that the
    constraint is entirely spurious, and only exists to force people to
    type needless casts. If there's a legitimate case for not allowing
    it to implicitly convert, then a cast, too, would cause undefined
    behavior (like trying to cast int ** to void **)

    Also, i was certain there was a table in the rationale document that
    implied this was allowed - maybe it was in POSIX.

    > When you try this with gcc, it will issue a warning regardless of
    > dialect settings. Other compilers might make it an error.
    >
    > S.
     
    Jordan Abel, Oct 29, 2005
    #4
  5. Greg Comeau Guest

    In article <>,
    <> wrote:
    >Skarmander, thank you for your response. I do appreciate it.
    >
    >I know they aren't equal types -- although char*[] is implicitly
    >convertible to char** (but obviously not the other way around).
    >
    >I did verify with Comeau's online compiler that C in strict mode will
    >not allow the conversion (the non-strict mode is tolerant of the
    >conversion). However, Comeau's C++ compiler in strict mode does allow
    >the conversion.
    >
    >Is C++ really more lenient in this respect? (no response required. I
    >know that if I want an answer I'll have to first search the C++
    >standard then post in comp.lang.c++ if I'm lost).
    >
    >It's unfortunate that C is so strict about this. I really strive to be
    >const-correct in my code, and if my function is going to take 'char**'
    >argument but not modify it, then it seems prudent to indicate this with
    >'const char * const *'. But expecting other people to cast is even
    >more undesirable.
    >
    >Does anyone know why C is so strict in this area? Is this something
    >that could be safely less-strict?


    Can you post exactly the line of code you're saying Comeau C accepted
    in strict mode but Comeau C++ rejected in strict mode? Thanks.
    --
    Greg Comeau / Celebrating 20 years of Comeauity!
    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?
     
    Greg Comeau, Oct 29, 2005
    #5
  6. Greg Comeau Guest

    In article <>,
    Jordan Abel <> wrote:
    >On 2005-10-28, Skarmander <> wrote:
    >> wrote:
    >>> Is char** (or char*[]) implicitly convertible to 'const char * const
    >>> *'?

    >> You put this in parentheses like they're equal types. They're not.

    >No, but char*[] is implicitly convertable to char **.
    >
    >>> I couldn't find anything about it in the standard. MSVS 8.0 allows
    >>> this. I'm curious if I'll run into trouble with other compilers like
    >>> GCC though.

    >>
    >> The answer is no, these implicit conversions are not allowed. An
    >> explicit cast is required. From the FAQ:
    >> http://www.eskimo.com/~scs/C-faq/q11.10.html.

    >
    >I'd like to know the justification for this. Is there or might there
    >be a system on which const pointers have a different representation
    >than non-const ones?
    >
    >You (and that FAQ) seem to think that a cast would work, and would
    >not cause undefined behavior, which makes me think that the
    >constraint is entirely spurious, and only exists to force people to
    >type needless casts. If there's a legitimate case for not allowing
    >it to implicitly convert, then a cast, too, would cause undefined
    >behavior (like trying to cast int ** to void **)
    >
    >Also, i was certain there was a table in the rationale document that
    >implied this was allowed - maybe it was in POSIX.



    Check out http://www.comeaucomputing.com/techtalk/#deconstutoh
    --
    Greg Comeau / Celebrating 20 years of Comeauity!
    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?
     
    Greg Comeau, Oct 29, 2005
    #6
  7. Guest

    It was the other way around. C++ strict mode accepted it. C strict
    mode rejected it. Here's the code:

    void test(const char * const * strArray)
    {
    }

    int main()
    {
    char** x = 0;
    test(x);
    return 0;
    }
     
    , Oct 29, 2005
    #7
  8. Guest

    Greg,

    I understand why 'char**' is not convertible to 'const char**'. Here's
    why "char**" is not convertible to "const char**". Here's how I
    explain it to others. Let us see what could happen if the conversion
    was allowed:

    void foo(const char** strArray)
    {
    strArray[0] = "Hello"; // This is OK for const char**
    }

    void bar()
    {
    char s1[] = "This is"; // Creates an array of characters that are
    initialized with the string "This is"
    char s2[] = "a test"; // <same as above>
    char*[] strArray = {s1, s2}; // Creates an array of pointers to
    strings. Neither is constant.

    foo(strArray); // Uh-oh strArray[0] now points to a constant
    string, which I shouldn't be able to modify.

    // According to the type of strArray, the following statement is
    allowed.
    // However, strArray[0] points to an area of constant memory (this
    could in theory lie on a ROM chip)
    strArray[0][0] = 'F'; // Ooops. Attempting to modify constant
    memory. Undefined behavior ensues!!!
    }



    But I don't see where problems could pop up if 'char**' is converted to
    'const char * const *' -- or am I missing something?
     
    , Oct 29, 2005
    #8
  9. Jordan Abel Guest

    On 2005-10-29, Greg Comeau <> wrote:
    > In article <>,
    > Jordan Abel <> wrote:
    >>On 2005-10-28, Skarmander <> wrote:
    >>> wrote:
    >>>> Is char** (or char*[]) implicitly convertible to 'const char * const
    >>>> *'?
    >>> You put this in parentheses like they're equal types. They're not.

    >>No, but char*[] is implicitly convertable to char **.
    >>
    >>>> I couldn't find anything about it in the standard. MSVS 8.0 allows
    >>>> this. I'm curious if I'll run into trouble with other compilers like
    >>>> GCC though.
    >>>
    >>> The answer is no, these implicit conversions are not allowed. An
    >>> explicit cast is required. From the FAQ:
    >>> http://www.eskimo.com/~scs/C-faq/q11.10.html.

    >>
    >>I'd like to know the justification for this. Is there or might there
    >>be a system on which const pointers have a different representation
    >>than non-const ones?
    >>
    >>You (and that FAQ) seem to think that a cast would work, and would
    >>not cause undefined behavior, which makes me think that the
    >>constraint is entirely spurious, and only exists to force people to
    >>type needless casts. If there's a legitimate case for not allowing
    >>it to implicitly convert, then a cast, too, would cause undefined
    >>behavior (like trying to cast int ** to void **)
    >>
    >>Also, i was certain there was a table in the rationale document that
    >>implied this was allowed - maybe it was in POSIX.

    >
    >
    > Check out http://www.comeaucomputing.com/techtalk/#deconstutoh


    I don't get it - I mean, i _get_ it, but i don't see how you could
    do this inadvertently. Forbidding something which doesn't actually
    violate const rules just because a programmer could use it to make a
    deliberate attempt to do so doesn't make sense.

    Besides, if i look at the table, [found it in the posix exec()
    manpage] which i misread the first time,

    const char * const *ppcc = ppc;

    which you suggest instead, is also forbidden.
     
    Jordan Abel, Oct 29, 2005
    #9
  10. Jordan Abel Guest

    On 2005-10-29, <> wrote:
    > Greg,
    >
    > I understand why 'char**' is not convertible to 'const char**'. Here's
    > why "char**" is not convertible to "const char**". Here's how I
    > explain it to others. Let us see what could happen if the conversion
    > was allowed:
    >
    > void foo(const char** strArray)
    > {
    > strArray[0] = "Hello"; // This is OK for const char**
    >}


    Well, that's also ok for char**, since string literals are of type
    char * in c. The general idea still stands, though.

    The thing that irritates me is that despite all this, it's _trivial_
    to violate const in C without resorting to all this.

    const char foo[] = "mystring";
    char *constviol = strchr(foo,*foo);
     
    Jordan Abel, Oct 29, 2005
    #10
  11. Greg Comeau Guest

    In article <>,
    <> wrote:
    >It was the other way around. C++ strict mode accepted it. C strict
    >mode rejected it. Here's the code:
    >
    >void test(const char * const * strArray)
    >{
    >}
    >
    >int main()
    >{
    > char** x = 0;
    > test(x);
    > return 0;
    >}


    Oops, I understand what you said but wrote the wrong thing.
    Anyway, that's for the exact example: yes, I agree that C++
    strict should accept it and C strict should reject it, for
    better or worse.
    --
    Greg Comeau / Celebrating 20 years of Comeauity!
    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?
     
    Greg Comeau, Oct 29, 2005
    #11
  12. Greg Comeau Guest

    In article <>,
    <> wrote:
    >I understand why 'char**' is not convertible to 'const char**'. Here's
    >why "char**" is not convertible to "const char**". Here's how I
    >explain it to others. Let us see what could happen if the conversion
    >was allowed:
    >
    >void foo(const char** strArray)
    >{
    > strArray[0] = "Hello"; // This is OK for const char**
    >}
    >
    >void bar()
    >{
    > char s1[] = "This is"; // Creates an array of characters that are
    >initialized with the string "This is"
    > char s2[] = "a test"; // <same as above>
    > char*[] strArray = {s1, s2}; // Creates an array of pointers to
    >strings. Neither is constant.


    You make a typo, should be char *strArray[] = ...

    > foo(strArray); // Uh-oh strArray[0] now points to a constant
    >string, which I shouldn't be able to modify.


    It may not point to a const string, but at least you're trying
    to make the promise that it might.

    > // According to the type of strArray, the following statement is
    >allowed.
    > // However, strArray[0] points to an area of constant memory (this
    >could in theory lie on a ROM chip)
    > strArray[0][0] = 'F'; // Ooops. Attempting to modify constant
    >memory. Undefined behavior ensues!!!


    Since you use the ame name inside bar and as the parameter
    to the function, it's unclear which strArray you're referring to.

    Certainly the one in strArray would be a problem w/o a cast because
    of the const specification for it.

    However, the strArray in foo has a similar problem but because
    C does not actually say that the declared type of a string literal
    is literally a const char[?], as C does, there is a type hole of sorts
    here, that is, whether it is ok in a given implementation whether
    string literals are unique and also whether it is ok to write into them
    with no ill effect(s).

    >}
    >
    >But I don't see where problems could pop up if 'char**' is converted to
    >'const char * const *' -- or am I missing something?


    There is no problem that I'm aware of this moment.
    I think Standard C was being overly cautious. As I recall
    the situation, it's definition of compatible type is too strong
    and although it lets so-called top level qualifications to be
    different but compatible, it does not apply the rule recursively.
    Standard C++ specifies a rather incomprehensible formala at first
    glance but is a case where the English meaning of it is easier
    to grok though the specification is precise, as it should be.
    --
    Greg Comeau / Celebrating 20 years of Comeauity!
    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?
     
    Greg Comeau, Oct 29, 2005
    #12
  13. Greg Comeau Guest

    In article <>,
    Jordan Abel <> wrote:
    >On 2005-10-29, Greg Comeau <> wrote:
    >> In article <>,
    >> Jordan Abel <> wrote:
    >>>On 2005-10-28, Skarmander <> wrote:
    >>>> wrote:
    >>>>> Is char** (or char*[]) implicitly convertible to 'const char * const
    >>>>> *'?
    >>>> You put this in parentheses like they're equal types. They're not.
    >>>No, but char*[] is implicitly convertable to char **.
    >>>
    >>>>> I couldn't find anything about it in the standard. MSVS 8.0 allows
    >>>>> this. I'm curious if I'll run into trouble with other compilers like
    >>>>> GCC though.
    >>>>
    >>>> The answer is no, these implicit conversions are not allowed. An
    >>>> explicit cast is required. From the FAQ:
    >>>> http://www.eskimo.com/~scs/C-faq/q11.10.html.
    >>>
    >>>I'd like to know the justification for this. Is there or might there
    >>>be a system on which const pointers have a different representation
    >>>than non-const ones?
    >>>
    >>>You (and that FAQ) seem to think that a cast would work, and would
    >>>not cause undefined behavior, which makes me think that the
    >>>constraint is entirely spurious, and only exists to force people to
    >>>type needless casts. If there's a legitimate case for not allowing
    >>>it to implicitly convert, then a cast, too, would cause undefined
    >>>behavior (like trying to cast int ** to void **)
    >>>
    >>>Also, i was certain there was a table in the rationale document that
    >>>implied this was allowed - maybe it was in POSIX.

    >>
    >>
    >> Check out http://www.comeaucomputing.com/techtalk/#deconstutoh

    >
    >I don't get it - I mean, i _get_ it, but i don't see how you could
    >do this inadvertently. Forbidding something which doesn't actually
    >violate const rules just because a programmer could use it to make a
    >deliberate attempt to do so doesn't make sense.


    I don't get what you don't get :) That is, doesn't my example
    show specifically how if it were allowed how one could violate constness?

    >Besides, if i look at the table, [found it in the posix exec()
    >manpage] which i misread the first time,
    >
    >const char * const *ppcc = ppc;
    >
    >which you suggest instead, is also forbidden.


    Well, my escape was the last line of #deconstutoh,
    since I can't really believe Standard C says it it is forbidden,
    even though I know it does :)
    --
    Greg Comeau / Celebrating 20 years of Comeauity!
    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?
     
    Greg Comeau, Oct 29, 2005
    #13
  14. Greg Comeau Guest

    In article <>,
    Jordan Abel <> wrote:
    >On 2005-10-29, <> wrote:
    >> Greg,
    >>
    >> I understand why 'char**' is not convertible to 'const char**'. Here's
    >> why "char**" is not convertible to "const char**". Here's how I
    >> explain it to others. Let us see what could happen if the conversion
    >> was allowed:
    >>
    >> void foo(const char** strArray)
    >> {
    >> strArray[0] = "Hello"; // This is OK for const char**
    >>}

    >
    >Well, that's also ok for char**, since string literals are of type
    >char * in c. The general idea still stands, though.
    >
    >The thing that irritates me is that despite all this, it's _trivial_
    >to violate const in C without resorting to all this.
    >
    >const char foo[] = "mystring";
    >char *constviol = strchr(foo,*foo);


    Indeed. Which is why the C++ committee plugged that hole in the
    type system.
    --
    Greg Comeau / Celebrating 20 years of Comeauity!
    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?
     
    Greg Comeau, Oct 29, 2005
    #14
  15. Greg Comeau Guest

    In article <>,
    Jordan Abel <> wrote:
    >On 2005-10-28, Skarmander <> wrote:
    >> ...
    >> The answer is no, these implicit conversions are not allowed. An
    >> explicit cast is required. From the FAQ:
    >> http://www.eskimo.com/~scs/C-faq/q11.10.html.

    >
    >I'd like to know the justification for this. Is there or might there
    >be a system on which const pointers have a different representation
    >than non-const ones?
    >
    >You (and that FAQ) seem to think that a cast would work, and would
    >not cause undefined behavior, which makes me think that the
    >constraint is entirely spurious, and only exists to force people to
    >type needless casts. If there's a legitimate case for not allowing
    >it to implicitly convert, then a cast, too, would cause undefined
    >behavior (like trying to cast int ** to void **)


    AFAIRecall, you are correct: the cast is not required to make it
    work and hence it's not a case of "would work" but _could_ work.
    --
    Greg Comeau / Celebrating 20 years of Comeauity!
    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?
     
    Greg Comeau, Oct 29, 2005
    #15
  16. Jordan Abel Guest

    On 2005-10-29, Greg Comeau <> wrote:
    >>I don't get it - I mean, i _get_ it, but i don't see how you could
    >>do this inadvertently. Forbidding something which doesn't actually
    >>violate const rules just because a programmer could use it to make
    >>a deliberate attempt to do so doesn't make sense.

    >
    > I don't get what you don't get :) That is, doesn't my example
    > show specifically how if it were allowed how one could violate
    > constness?


    I don't get how someone could do it and not know they were doing it
    - you claimed it could lead to an 'inadvertent' mistake
     
    Jordan Abel, Oct 29, 2005
    #16
  17. Jordan Abel Guest

    On 2005-10-29, Greg Comeau <> wrote:
    > In article <>,
    > Jordan Abel <> wrote:
    >>On 2005-10-29, <> wrote:
    >>> Greg,
    >>>
    >>> I understand why 'char**' is not convertible to 'const char**'. Here's
    >>> why "char**" is not convertible to "const char**". Here's how I
    >>> explain it to others. Let us see what could happen if the conversion
    >>> was allowed:
    >>>
    >>> void foo(const char** strArray)
    >>> {
    >>> strArray[0] = "Hello"; // This is OK for const char**
    >>>}

    >>
    >>Well, that's also ok for char**, since string literals are of type
    >>char * in c. The general idea still stands, though.
    >>
    >>The thing that irritates me is that despite all this, it's _trivial_
    >>to violate const in C without resorting to all this.
    >>
    >>const char foo[] = "mystring";
    >>char *constviol = strchr(foo,*foo);

    >
    > Indeed. Which is why the C++ committee plugged that hole in the
    > type system.


    How'd they manage that? Just out of curiosity, I know it's off-topic
     
    Jordan Abel, Oct 29, 2005
    #17
  18. Skarmander Guest

    Re: Is char** (or char*[]) implicitly convertible to 'const char* const *'?

    Jordan Abel wrote:
    > On 2005-10-29, Greg Comeau <> wrote:
    >
    >>In article <>,
    >>Jordan Abel <> wrote:
    >>
    >>>On 2005-10-29, <> wrote:
    >>>
    >>>The thing that irritates me is that despite all this, it's _trivial_
    >>>to violate const in C without resorting to all this.
    >>>
    >>>const char foo[] = "mystring";
    >>>char *constviol = strchr(foo,*foo);

    >>
    >>Indeed. Which is why the C++ committee plugged that hole in the
    >>type system.

    >
    >
    > How'd they manage that? Just out of curiosity, I know it's off-topic


    They cheated. :) C++ allows overloading, so there are *two* strchrs in
    C++: "const char* strchr(const char*, int)" and "char* strchr(char*,
    int)". Since foo is convertible to a const char* but not a char*, the
    call above is invalid since the strchr() that returns a const char* will
    be called.

    S.
     
    Skarmander, Oct 29, 2005
    #18
  19. Skarmander Guest

    Re: Is char** (or char*[]) implicitly convertible to 'const char* const *'?

    Skarmander wrote:
    > Jordan Abel wrote:
    >
    >> On 2005-10-29, Greg Comeau <> wrote:
    >>
    >>> In article <>,
    >>> Jordan Abel <> wrote:
    >>>
    >>>> On 2005-10-29, <>
    >>>> wrote:
    >>>>
    >>>> The thing that irritates me is that despite all this, it's _trivial_
    >>>> to violate const in C without resorting to all this.
    >>>>
    >>>> const char foo[] = "mystring";
    >>>> char *constviol = strchr(foo,*foo);
    >>>
    >>>
    >>> Indeed. Which is why the C++ committee plugged that hole in the
    >>> type system.

    >>
    >>
    >>
    >> How'd they manage that? Just out of curiosity, I know it's off-topic

    >
    >
    > They cheated. :) C++ allows overloading, so there are *two* strchrs in
    > C++: "const char* strchr(const char*, int)" and "char* strchr(char*,
    > int)". Since foo is convertible to a const char* but not a char*, the
    > call above is invalid since the strchr() that returns a const char* will
    > be called.
    >


    Actually, I could be wrong. Not about the overloaded versions, but I may
    be wrong on how the overloading and converting conspire. I haven't
    written C++ in ages. Please correct and/or apply grain of salt as necessary.

    S.
     
    Skarmander, Oct 29, 2005
    #19
  20. Greg Comeau Guest

    In article <>,
    Jordan Abel <> wrote:
    >On 2005-10-29, Greg Comeau <> wrote:
    >>>I don't get it - I mean, i _get_ it, but i don't see how you could
    >>>do this inadvertently. Forbidding something which doesn't actually
    >>>violate const rules just because a programmer could use it to make
    >>>a deliberate attempt to do so doesn't make sense.

    >>
    >> I don't get what you don't get :) That is, doesn't my example
    >> show specifically how if it were allowed how one could violate
    >> constness?

    >
    >I don't get how someone could do it and not know they were doing it


    Newbies do everything, for starters.

    >- you claimed it could lead to an 'inadvertent' mistake


    I probably did claim that, and probably still do.
    Take the code maintainance process, for one.
    --
    Greg Comeau / Celebrating 20 years of Comeauity!
    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?
     
    Greg Comeau, Oct 29, 2005
    #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. AlesD
    Replies:
    3
    Views:
    479
    Victor Bazarov
    Aug 10, 2004
  2. Tom Howard
    Replies:
    2
    Views:
    327
  3. Replies:
    10
    Views:
    585
    Dave Thompson
    Sep 5, 2005
  4. lovecreatesbeauty
    Replies:
    1
    Views:
    1,057
    Ian Collins
    May 9, 2006
  5. Replies:
    4
    Views:
    337
    redblue
    Nov 3, 2007
Loading...

Share This Page