[comp.lang.c] What is strdup

jik@athena.mit.edu (Jonathan I. Kamens) (02/19/91)

(Note the Followup-To.)

In article <1991Feb19.004526.16033@onion.rain.com> jeff@onion.rain.com (Jeff Beadles) writes:

    In <1991Feb18.154159.430@persoft.com> dag@persoft.com (Daniel Glasser) writes:
    > [he asks why the temporary char *ret inside strdup is declared static]

   A creature of habit, I suppose.  I've been bitten too often when I return
   something from a function that isn't static.  (int's, for example.)  For this
   case, it really doesn't matter.

I would suggest that if you can't tell the difference between a value
that is safe to return from a function, and a value that is not,
you're better off letting other people post code to the net.  I posted
a working version of strdup() the same day the question was asked, and
yet we have all these people posting inferior versions (That's not my
ego speaking, for all of you who are getting ready to pounce on your
"F" key for flaming me about saying, "My code is better than yours!"
That's just simple fact.  The version I posted had no errors; if you
think it did, feel free to point them out.).

Yes, I know there are lags in news transmission, and it's quite
possible that you didn't see my posting before posting yours.  I
wouldn't be mentioning the duplication at all if it weren't for the
fact that your code was wrong.

You should not declare variables static when they don't have to be
static.  Code which declares a variable static when that variable has
absolutely no reason whatsover to be static is wrong.

   It's kinda like the braces around the malloc failure.  They're not technically
   required, but it's not a bad habit. :-)

Braces around a one-line "if" block are good programming because they
don't affect the compiled code, and because they will save you from
problems if you change things later so that there is more than one
statement in the body of the "if," and because if the statement is
actually a macro that has multiple statements in it, the braces
protect you from any dangerous results.

On the other hand, declaring a variable static when it doesn't have to
be *does* affect the compiler output, by keeping a variable in memory
all the time when it doesn't have to be.  Furthermore, unless you plan
to seriously change the functionality of strdup() at some point in the
future, there is no chance that that variable will ever need to be
static, so there is no "preventative" excuse to make it static.

    >Nit #2:	You should simplify your expression in the "malloc()", that is,
    >		sizeof(char) * strlen(foo) + sizeof(char)
    >	could be written
    >		sizeof(char) * (strlen(foo) + 1)

   Untrue.  What if sizeof(char) != 1?  Yours will break, and mine will work.

You're wrong.  Both expressions above will result in the proper value,
whether sizeof(char) is 1 or not.  Your expression takes the number of
characters in the string, multiplies it by the size of a character,
and adds the size of a character.  The other suggested expression
takes the number of characters in the string, adds 1 to it, and
multiples the result by the size of a character.  The fact that these
will result in the same value should be obvious.  And, incidentally, I
agree with the previous poster that the latter expression is clearer
than the former.

I'm sorry if I'm coming down a bit hard on you.  I guess I'm taking
out on you all the frustration I've been feeling for the past three
days, watching people post wrong or incomplete answers to a solved
problem with the solution has already been posted.  It's a bit
irritating.

Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

guy@auspex.auspex.com (Guy Harris) (02/20/91)

>   A creature of habit, I suppose.  I've been bitten too often when I return
>   something from a function that isn't static.  (int's, for example.)  For
>   this case, it really doesn't matter.
>
>I would suggest that if you can't tell the difference between a value
>that is safe to return from a function, and a value that is not,
>you're better off letting other people post code to the net.

Yup.  I'm really curious how the poster to whom you're responding had
gotten bitten by returning a non-static "int"; other code does so
successfully all the time.  The place where you tend to get bitten is
when you return a pointer *to* something that's not static, not when you
return something that's not static....

>   Untrue.  What if sizeof(char) != 1?  Yours will break, and mine will work.
>
>You're wrong.  Both expressions above will result in the proper value,
>whether sizeof(char) is 1 or not.

And, on top of that, to quote the ANSI C standard:

	   When applied to an operand that has type "char", "unsigned
	char", or "signed char", (or a qualified version thereof) the
	result is 1.

KKEYTE@ESOC.BITNET (Karl Keyte) (02/20/91)

In article <JIK.91Feb19015421@pit-manager.mit.edu>, jik@athena.mit.edu (Jonathan
I. Kamens) says:

>The version I posted had no errors; if you
>think it did, feel free to point them out.).

Hmmm.  No errors?  Cannot be verified according to theoretical computer
science!

Karl    :-)

fischer@iesd.auc.dk (Lars P. Fischer) (02/21/91)

>>>>> dag@persoft.com (Daniel Glasser) writes:

Daniel>Nit #2: You should simplify your expression in the "malloc()", that is,
Daniel>		sizeof(char) * strlen(foo) + sizeof(char)
Daniel>	  could be written
Daniel>		sizeof(char) * (strlen(foo) + 1)

>>>>> jeff@onion.rain.com (Jeff Beadles) then said:

Jeff> Untrue.  What if sizeof(char) != 1?  Yours will break, and mine
Jeff> will work.

Gimme a break. Are you going to tell us that

	A * (B + 1) != A * B + A

for A != 1 ?? If you can't handle basic arithmetic, what makes you
think you can write a C program?

/Lars
--
Lars Fischer,  fischer@iesd.auc.dk   | Beauty is a French phonetic corruption
CS Dept., Univ. of Aalborg, DENMARK. |                   - FZ

volpe@camelback.crd.ge.com (Christopher R Volpe) (02/21/91)

In article <FISCHER.91Feb20184612@thiele.iesd.auc.dk>,
fischer@iesd.auc.dk (Lars P. Fischer) writes:
|>>>>>> dag@persoft.com (Daniel Glasser) writes:
|>
|>Daniel>Nit #2: You should simplify your expression in the "malloc()",
that is,
|>Daniel>		sizeof(char) * strlen(foo) + sizeof(char)
|>Daniel>	  could be written
|>Daniel>		sizeof(char) * (strlen(foo) + 1)
                                       ^
                                       |-This paren isn't closed, and
                                         may be causing much of the confusion.

|>
|>>>>>> jeff@onion.rain.com (Jeff Beadles) then said:
|>
|>Jeff> Untrue.  What if sizeof(char) != 1?  Yours will break, and mine
|>Jeff> will work.
|>
|>Gimme a break. Are you going to tell us that
|>
|>	A * (B + 1) != A * B + A
|>
|>for A != 1 ?? If you can't handle basic arithmetic, what makes you
|>think you can write a C program?

I think Lars and Jeff are talking about different expressions here, due to
the missing closing parenthesis. Jeff saw the expression
         sizeof(char) * strlen(foo) + 1 (he didn't see the '(' before 'strlen')
and noted that this wouldn't be equal to 
         sizeof(char) * strlen(foo) + sizeof(char)
in the event that sizeof(char) != 1. This is absolutely true, but a moot
point since sizeof(char) == 1 by definition. 

However, Lars saw the expression
         sizeof(char) * (strlen(foo) + 1) (he added the missing paren)
and noted that this is equal to
         sizeof(char) *  strlen(foo) + sizeof(char)
by mathematical identity (distribution of multiplication over addition)
regardless of whether or not sizeof(char) == 1.

The non-expression originally posted by Daniel, however, was not what
either of them saw, and they each extrapolated in different directions
to arrive at what they thought Daniel intended to write. I hope this
clears up the confusion.

-Chris                       
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com

rob@meaddata.com (Robert E. Lancia) (02/23/91)

>>>>> dag@persoft.com (Daniel Glasser) writes:

Daniel>Nit #2: You should simplify your expression in the "malloc()", that is,
Daniel>		sizeof(char) * strlen(foo) + sizeof(char)
Daniel>	  could be written
Daniel>		sizeof(char) * (strlen(foo) + 1)


>>>>> jeff@onion.rain.com (Jeff Beadles) then said:

Jeff> Untrue.  What if sizeof(char) != 1?  Yours will break, and mine
Jeff> will work.


>>>>> fischer@iesd.auc.dk (Lars P. Fischer) then writes:

Lars> Gimme a break. Are you going to tell us that
Lars> A * (B + 1) != A * B + A
Lars> for A != 1 ?? If you can't handle basic arithmetic, what makes you
Lars> think you can write a C program?


I think Lars might have jumped the gun a bit here.  Maybe, just MAYBE, Jeff
mis-read Daniel's rewrite as

    sizeof(char) * strlen(foo) + 1

instead of (the correct)

    sizeof(char) * (strlen(foo) + 1)

If this were the case, his comment makes perfect sense.  Regardless, I'm
giving Jeff the benefit of the doubt and blaming his eye doctor! :^)
--
|Robert Lancia                  |  I have a split   |  Mead Data Central
|(513) 297-2560                 |  personality, and |  Data Services Division
|rob@pmserv.meaddata.com        |  these are HIS    |  P.O. Box 308
|...!uunet!meaddata!pmserv!rob  |  comments.        |  Dayton, Ohio  45401