supplementary C frequent answers

Discussion in 'C Programming' started by Ben Pfaff, Jan 3, 2004.

  1. Ben Pfaff

    Ben Pfaff Guest

    Over the last couple of years, and especially recently, I've
    built up a few "stock" answers that supplement the C FAQ. If
    anyone wants to review and comment on them, I've just now put
    them up on my webpage, at
    http://benpfaff.org/writings/clc

    --
    char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
    ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x1f6},*p=
    b,x,i=24;for(;p+=!*p;*p/=4)switch(x=*p&3)case 0:{return 0;for(p--;i--;i--)case
    2:{i++;if(1)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
    Ben Pfaff, Jan 3, 2004
    #1
    1. Advertising

  2. "Ben Pfaff" <> wrote in message
    news:...
    > Over the last couple of years, and especially recently, I've
    > built up a few "stock" answers that supplement the C FAQ. If
    > anyone wants to review and comment on them, I've just now put
    > them up on my webpage, at
    > http://benpfaff.org/writings/clc


    From that website:
    "Using strncpy() into a large buffer can be very inefficient. strncpy()
    always
    writes to every byte in the destination buffer, which can waste a lot of
    time
    if the destination buffer is much longer than the source string."

    Isn't this a QoI issue? According to the Standard,

    "The strncpy function copies not more than n characters (characters that
    follow a null character are not copied) from the array pointed to by s2 to
    the array pointed to by s1. If copying takes place between objects that
    overlap, the behavior is undefined."

    Please note the part in parenteses.

    Also from your website,

    "If the source string is longer than the size of the destination buffer,
    then strncpy() doesn't write a terminating null. So a call to strncpy() must
    be
    followed by explicitly writing a null terminator at the end of the
    destination
    buffer in most cases."

    Nothing simpler:

    strncpy(dest, src, n)[n-1] = 0;

    IMNSHO, strncpy() is far more advisable than strcpy().

    Lastly, "off-topic guidance message" is a good title in a context of a
    specific thread. As a general guidance, as e.g. on your website, it will
    most likely go unnoticed ("I never write off-topic posts, why should I waste
    my time reading it?").
    Something like "comp.lang.c topicality guidance" might be better. Just my
    £0.02.

    Peter
    Peter Pichler, Jan 3, 2004
    #2
    1. Advertising

  3. Peter Pichler wrote:

    > "Ben Pfaff" <> wrote in message
    > news:...
    >> Over the last couple of years, and especially recently, I've
    >> built up a few "stock" answers that supplement the C FAQ. If
    >> anyone wants to review and comment on them, I've just now put
    >> them up on my webpage, at
    >> http://benpfaff.org/writings/clc

    >
    > From that website:
    > "Using strncpy() into a large buffer can be very
    > inefficient. strncpy() always writes to every byte
    > in the destination buffer, which can waste a lot of
    > time if the destination buffer is much longer than
    > the source string."
    >
    > Isn't this a QoI issue?


    No.

    > According to the Standard,
    >
    > "The strncpy function copies not more than n characters (characters that
    > follow a null character are not copied) from the array pointed to by s2 to
    > the array pointed to by s1. If copying takes place between objects that
    > overlap, the behavior is undefined."
    >
    > Please note the part in parenteses.


    Please note the very next sentence: "If the array pointed to by s2 is a
    string that is shorter than n characters, null characters are appended to
    the copy in the array pointed to by s1, until n characters in all have been
    written."

    > Also from your website,
    >
    > "If the source string is longer than the size of the destination buffer,
    > then strncpy() doesn't write a terminating null. So a call to strncpy()
    > must be followed by explicitly writing a null terminator at the end of the
    > destination buffer in most cases."
    >
    > Nothing simpler:
    >
    > strncpy(dest, src, n)[n-1] = 0;


    Easy to forget to do that, though, and it assumes that dest is at least n
    bytes long, which it might not be.

    > IMNSHO, strncpy() is far more advisable than strcpy().


    That's like saying a screwdriver is more advisable than a hammer. It depends
    on what you're trying to do. strncpy's job is to copy part of a string,
    whereas strcpy's job is to copy a whole string. It is silly to use strncpy
    if your objective is to copy the whole string.

    > Lastly, "off-topic guidance message" is a good title in a context of a
    > specific thread. As a general guidance, as e.g. on your website, it will
    > most likely go unnoticed ("I never write off-topic posts, why should I
    > waste my time reading it?").
    > Something like "comp.lang.c topicality guidance" might be better. Just my
    > £0.02.


    Better, and it suggested "Guidance on finding the best newsgroup for your
    question" to me as a (rather verbose but otherwise perhaps more friendly)
    possibility.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
    Richard Heathfield, Jan 3, 2004
    #3
  4. Ben Pfaff

    pete Guest

    Peter Pichler wrote:
    >
    > "Ben Pfaff" <> wrote in message
    > news:...
    > > Over the last couple of years, and especially recently, I've
    > > built up a few "stock" answers that supplement the C FAQ. If
    > > anyone wants to review and comment on them, I've just now put
    > > them up on my webpage, at
    > > http://benpfaff.org/writings/clc

    >
    > From that website:
    > "Using strncpy() into a large buffer can be
    > very inefficient. strncpy() always writes to every byte in the
    > destination buffer, which can waste a lot of time
    > if the destination buffer is much longer than the source string."
    >
    > Isn't this a QoI issue?


    If you strncpy a zero length string source to
    a hundred byte length string destination,
    101 bytes of the destination string will be overwritten.

    If you strcpy a zero length string source to
    a hundred byte length string destination,
    1 byte of the destination string will be overwritten.

    --
    pete
    pete, Jan 3, 2004
    #4
  5. Richard Heathfield wrote:
    > Peter Pichler wrote:
    >> "If the source string is longer than the size of the destination buffer,
    >> then strncpy() doesn't write a terminating null. So a call to strncpy()
    >> must be followed by explicitly writing a null terminator at the end of the
    >> destination buffer in most cases."
    >>
    >> Nothing simpler:
    >>
    >> strncpy(dest, src, n)[n-1] = 0;

    >
    > Easy to forget to do that, though, and it assumes that dest is at least n
    > bytes long, which it might not be.


    If dest is less than n bytes long then the call to strncpy() is broken
    already.

    Jeremy.
    Jeremy Yallop, Jan 3, 2004
    #5
  6. "Richard Heathfield" <> wrote:
    > Peter Pichler wrote:

    (about strncpy() being inefiicient)
    > > Isn't this a QoI issue?

    >
    > No.
    >
    > Please note the very next sentence: "If the array pointed to by s2 is a
    > string that is shorter than n characters, null characters are appended to
    > the copy in the array pointed to by s1, until n characters in all have

    been
    > written."


    Doh! Richard, was it you running the reading for comprehension course? Where
    can I enroll?

    > > IMNSHO, strncpy() is far more advisable than strcpy().

    >
    > That's like saying a screwdriver is more advisable than a hammer. It

    depends
    > on what you're trying to do. strncpy's job is to copy part of a string,
    > whereas strcpy's job is to copy a whole string. It is silly to use strncpy
    > if your objective is to copy the whole string.


    In many cases, you don't know how long the source string is. If I should
    call strlen() first to find out, I could just as well use strncpy().

    Peter
    Peter Pichler, Jan 3, 2004
    #6
  7. Ben Pfaff wrote:
    > Over the last couple of years, and especially recently, I've
    > built up a few "stock" answers that supplement the C FAQ. If
    > anyone wants to review and comment on them, I've just now put
    > them up on my webpage, at
    > http://benpfaff.org/writings/clc


    | When are casts appropriate?
    |
    | Casts are generally undesirable, but there are several situations
    | where a cast legitimately comes in handy:
    [...]
    | * Passing a null pointer to a varargs function.

    More generally, calling a varargs function with any value whose type
    isn't compatible with what the function expects.

    Jeremy.
    Jeremy Yallop, Jan 3, 2004
    #7
  8. [Somebody] said
    > > > IMNSHO, strncpy() is far more advisable than strcpy().


    > "Richard Heathfield" <> wrote:


    > >
    > > That's like saying a screwdriver is more advisable than a hammer. It depends
    > > on what you're trying to do. strncpy's job is to copy part of a string,
    > > whereas strcpy's job is to copy a whole string. It is silly to use strncpy
    > > if your objective is to copy the whole string.


    That's a slightly limited way of looking at it; you could also say
    that strncpy's "job" is to copy all of a string up to a limit. Having
    that limit be within the target buffer's boundaries can be useful.

    "Peter Pichler" <> writes:

    > In many cases, you don't know how long the source string is. If I should
    > call strlen() first to find out, I could just as well use strncpy().


    All else being equal. In practice, I often find that the length may
    be needed for other reasons. I wouldn't bother making this point to a
    beginner, though.
    --
    Lowell Gilbert, embedded/networking software engineer, Boston area:
    resume/CV at http://be-well.ilk.org:8088/~lowell/resume/
    username/password "public"
    Lowell Gilbert, Jan 3, 2004
    #8
  9. Peter Pichler wrote:

    <snip>

    >> > IMNSHO, strncpy() is far more advisable than strcpy().

    >>
    >> That's like saying a screwdriver is more advisable than a hammer. It

    > depends
    >> on what you're trying to do. strncpy's job is to copy part of a string,
    >> whereas strcpy's job is to copy a whole string. It is silly to use
    >> strncpy if your objective is to copy the whole string.

    >
    > In many cases, you don't know how long the source string is. If I should
    > call strlen() first to find out, I could just as well use strncpy().


    Um, I think you really *should* sign up for that course, Peter. :)

    If you need the whole string, you simply *have* to know how much storage
    you'll need if you want to make a copy of it, and you *must* have the right
    amount of storage available.

    Having ascertained that "this" will fit into "that", by all means call
    strncpy instead of strncpy if you really like typing all that much, but it
    adds no extra safety and does not communicate your intent as well as strcpy
    does.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
    Richard Heathfield, Jan 3, 2004
    #9
  10. "Richard Heathfield" <> wrote in message
    news:bt6ndn$rf9$...
    > Peter Pichler wrote:
    > > In many cases, you don't know how long the source string is. If I should
    > > call strlen() first to find out, I could just as well use strncpy().

    >
    > Um, I think you really *should* sign up for that course, Peter. :)


    ("that" being "reading for comprehension", just for the benefit of innocent
    bystanders)

    No doubt ;-)

    > If you need the whole string, you simply *have* to know how much storage
    > you'll need if you want to make a copy of it, and you *must* have the

    right
    > amount of storage available.


    Perhaps we both need the course ;-) What if I don't care about the /whole/
    string, but need to limit how much to copy because I know the length of the
    destination buffer and know that it may not be long enough? Strange as it
    may seem, I have just recently appeared in exactly that situation. To be
    fair, I did not realize that strncpy() filled up the remaining space with
    zeros. <eom>

    Peter
    Peter Pichler, Jan 3, 2004
    #10
  11. Ben Pfaff

    Joe Wright Guest

    pete wrote:
    >
    > Peter Pichler wrote:
    > >
    > > "Ben Pfaff" <> wrote in message
    > > news:...
    > > > Over the last couple of years, and especially recently, I've
    > > > built up a few "stock" answers that supplement the C FAQ. If
    > > > anyone wants to review and comment on them, I've just now put
    > > > them up on my webpage, at
    > > > http://benpfaff.org/writings/clc

    > >
    > > From that website:
    > > "Using strncpy() into a large buffer can be
    > > very inefficient. strncpy() always writes to every byte in the
    > > destination buffer, which can waste a lot of time
    > > if the destination buffer is much longer than the source string."
    > >
    > > Isn't this a QoI issue?

    >
    > If you strncpy a zero length string source to
    > a hundred byte length string destination,
    > 101 bytes of the destination string will be overwritten.
    >

    Show me. strncpy() will write n characters to the destination.

    > If you strcpy a zero length string source to
    > a hundred byte length string destination,
    > 1 byte of the destination string will be overwritten.
    >
    > --
    > pete


    --
    Joe Wright http://www.jw-wright.com
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
    Joe Wright, Jan 3, 2004
    #11
  12. Peter Pichler wrote:

    > What if I don't care about the /whole/
    > string, but need to limit how much to copy because I know the length of
    > the destination buffer and know that it may not be long enough?


    If you don't care about the whole string, strcpy is the Wrong Thing for that
    task, because strcpy /does/ copy the whole string.

    Personally, I never use strncpy. If I care about the whole string, I make
    sure the receiving buffer is big enough. If I don't care about the whole
    string, I don't treat it /as/ a string (since the bit that I care about
    /isn't/ a string), and I would favour mem* routines rather than str*
    routines for that purpose.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
    Richard Heathfield, Jan 3, 2004
    #12
  13. Ben Pfaff

    Ben Pfaff Guest

    Jeremy Yallop <> writes:

    > Ben Pfaff wrote:
    > > Over the last couple of years, and especially recently, I've
    > > built up a few "stock" answers that supplement the C FAQ. If
    > > anyone wants to review and comment on them, I've just now put
    > > them up on my webpage, at
    > > http://benpfaff.org/writings/clc

    >
    > | When are casts appropriate?
    > |
    > | Casts are generally undesirable, but there are several situations
    > | where a cast legitimately comes in handy:
    > [...]
    > | * Passing a null pointer to a varargs function.
    >
    > More generally, calling a varargs function with any value whose type
    > isn't compatible with what the function expects.


    Most of the time, though, such conversions are more reasonably
    done without a cast. (In my opinion, of course.)
    --
    "I hope, some day, to learn to read.
    It seems to be even harder than writing."
    --Richard Heathfield
    Ben Pfaff, Jan 3, 2004
    #13
  14. Ben Pfaff

    Servé Lau Guest

    "Ben Pfaff" <> wrote in message
    news:...
    > Over the last couple of years, and especially recently, I've
    > built up a few "stock" answers that supplement the C FAQ. If
    > anyone wants to review and comment on them, I've just now put
    > them up on my webpage, at
    > http://benpfaff.org/writings/clc


    IMO, the article "why should toupper()'s argument be cast to unsigned char?"
    is not explained very well.
    What do you mean with "If char is signed, then some characters have negative
    values". It could use an example.

    I'd also elaborate about the valid return values from main in the article
    "how should main be declared". Maybe the difference between implicit return
    values in C89 and C99 would fit in there too (or put it in another article)

    The article about malloc's return value could use an example for its third
    point. "If you cast to the wrong type by accident, odd failures can result"
    What odd failures? Convince me.
    Servé Lau, Jan 3, 2004
    #14
  15. Ben Pfaff <> writes:
    > Jeremy Yallop <> writes:
    >
    > > Ben Pfaff wrote:
    > > > Over the last couple of years, and especially recently, I've
    > > > built up a few "stock" answers that supplement the C FAQ. If
    > > > anyone wants to review and comment on them, I've just now put
    > > > them up on my webpage, at
    > > > http://benpfaff.org/writings/clc

    > >
    > > | When are casts appropriate?
    > > |
    > > | Casts are generally undesirable, but there are several situations
    > > | where a cast legitimately comes in handy:
    > > [...]
    > > | * Passing a null pointer to a varargs function.
    > >
    > > More generally, calling a varargs function with any value whose type
    > > isn't compatible with what the function expects.

    >
    > Most of the time, though, such conversions are more reasonably
    > done without a cast. (In my opinion, of course.)


    Can you give some examples?

    Here are a couple of cases where (IMHO) a cast is appropriate:

    int *ptr = <whatever>;

    printf("sizeof(ptr) = %d\n", (int)sizeof(ptr));
    printf("ptr = [%p]\n", (void*)ptr);

    In C99, you can avoid the cast in the first printf by using "%zu", but
    that's not universally supported yet. (I might use unsigned long
    rather than int, but I'm reasonably certain in this case that
    sizeof(ptr) <= INT_MAX.)

    In the second printf, I don't see a good way to avoid the cast.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
    Schroedinger does Shakespeare: "To be *and* not to be"
    (Note new e-mail address)
    Keith Thompson, Jan 3, 2004
    #15
  16. Ben Pfaff

    Ben Pfaff Guest

    "Servé Lau" <> writes:

    > "Ben Pfaff" <> wrote in message
    > news:...
    > > Over the last couple of years, and especially recently, I've
    > > built up a few "stock" answers that supplement the C FAQ. If
    > > anyone wants to review and comment on them, I've just now put
    > > them up on my webpage, at
    > > http://benpfaff.org/writings/clc

    >
    > IMO, the article "why should toupper()'s argument be cast to unsigned char?"
    > is not explained very well.
    > What do you mean with "If char is signed, then some characters have negative
    > values". It could use an example.


    Okay, I've updated it. (Changes may take a minute or two to
    propagate.)

    > I'd also elaborate about the valid return values from main in the article
    > "how should main be declared". Maybe the difference between implicit return
    > values in C89 and C99 would fit in there too (or put it in another article)


    Sure, good suggestion.

    > The article about malloc's return value could use an example for its third
    > point. "If you cast to the wrong type by accident, odd failures can result"
    > What odd failures? Convince me.


    I don't recall at the moment, but it's definitely true--I've seen
    them. Alignment-related failures surely, and I think there are
    others.
    --
    "For those who want to translate C to Pascal, it may be that a lobotomy
    serves your needs better." --M. Ambuhl

    "Here are the steps to create a C-to-Turbo-Pascal translator..." --H. Schildt
    Ben Pfaff, Jan 3, 2004
    #16
  17. Ben Pfaff wrote:

    > "Serve' Lau" <> writes:
    >
    >> The article about malloc's return value could use an example for its
    >> third point. "If you cast to the wrong type by accident, odd failures can
    >> result" What odd failures? Convince me.

    >
    > I don't recall at the moment, but it's definitely true--I've seen
    > them. Alignment-related failures surely, and I think there are
    > others.


    Consider a C90 implementation which stores returned pointers in one
    register, and returned integers in another. If you forget to provide a
    correct prototype for a function returning a pointer, such as malloc, the
    implementation is obliged to assume that the function in question returns
    int, rather than a pointer type, and therefore your code could receive a
    garbage value from the integer register rather than the value that malloc
    actually returns, which the implementation correctly stores in the pointer
    register.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
    Richard Heathfield, Jan 3, 2004
    #17
  18. Ben Pfaff

    Ben Pfaff Guest

    Richard Heathfield <> writes:

    > Ben Pfaff wrote:
    >
    > > "Serve' Lau" <> writes:
    > >
    > >> The article about malloc's return value could use an example for its
    > >> third point. "If you cast to the wrong type by accident, odd failures can
    > >> result" What odd failures? Convince me.

    > >
    > > I don't recall at the moment, but it's definitely true--I've seen
    > > them. Alignment-related failures surely, and I think there are
    > > others.

    >
    > Consider a C90 implementation which stores returned pointers in one
    > register, and returned integers in another. If you forget to provide a
    > correct prototype for a function returning a pointer, such as malloc, the
    > implementation is obliged to assume that the function in question returns
    > int, rather than a pointer type, and therefore your code could receive a
    > garbage value from the integer register rather than the value that malloc
    > actually returns, which the implementation correctly stores in the pointer
    > register.


    Such a problem would be covered by the second point, "Casting its
    return value can mask a failure to #include <stdlib.h>, which
    leads to undefined behavior." We are discussing the third point,
    "If you cast to the wrong type by accident, odd failures can
    result."
    --
    "I ran it on my DeathStation 9000 and demons flew out of my nose." --Kaz
    Ben Pfaff, Jan 3, 2004
    #18
  19. "Richard Heathfield" <> wrote:
    > Ben Pfaff wrote:
    > > "Serve' Lau" <> writes:
    > >
    > >> The article about malloc's return value could use an example for its
    > >> third point. "If you cast to the wrong type by accident, odd failures

    can
    > >> result" What odd failures? Convince me.

    > >
    > > I don't recall at the moment, but it's definitely true--I've seen
    > > them. Alignment-related failures surely, and I think there are
    > > others.

    >
    > Consider a C90 implementation which stores returned pointers in one
    > register, and returned integers in another. If you forget to provide a
    > correct prototype for a function returning a pointer, such as malloc [...]


    With more missing context in this message, I thought that he was talking
    about /having/ a prototype yet casting to the wrong type. Can you see any
    problems with that other than failing to compile?
    Peter Pichler, Jan 3, 2004
    #19
  20. Ben Pfaff wrote:

    <snip>

    > Such a problem would be covered by the second point, "Casting its
    > return value can mask a failure to #include <stdlib.h>, which
    > leads to undefined behavior." We are discussing the third point,
    > "If you cast to the wrong type by accident, odd failures can
    > result."


    Oops. Sorry about that.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
    Richard Heathfield, Jan 4, 2004
    #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. Thotatri

    Frequent session time Expiry

    Thotatri, Jul 21, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    457
    Thotatri
    Jul 21, 2003
  2. Jon Davis

    Frequent re-precompile on large site

    Jon Davis, Oct 27, 2006, in forum: ASP .Net
    Replies:
    2
    Views:
    305
    Jon Davis
    Oct 29, 2006
  3. Andrew Walrond

    Supplementary groups

    Andrew Walrond, Nov 20, 2003, in forum: Ruby
    Replies:
    0
    Views:
    95
    Andrew Walrond
    Nov 20, 2003
  4. Jan Pokorný
    Replies:
    1
    Views:
    180
    Jan Pokorný
    Mar 11, 2012
  5. Malcolm McLean

    strsup - supplementary string functions

    Malcolm McLean, Jan 22, 2013, in forum: C Programming
    Replies:
    19
    Views:
    377
    Tim Rentsch
    Feb 3, 2013
Loading...

Share This Page