strdup

K

Keith Thompson

CBFalconer said:
No it isn't.

Yes, it is. C99 7.26.11, under "Future library directions":

Function names that begin with str, mem, or wcs and a lowercase
letter may be added to the declarations in the <string.h> header.
 
C

CBFalconer

Keith said:
Yes, it is. C99 7.26.11, under "Future library directions":

Function names that begin with str, mem, or wcs and a lowercase
letter may be added to the declarations in the <string.h> header.

No it isn't. See:

7.1.3 Reserved identifiers

[#1] Each header declares or defines all identifiers listed
in its associated subclause, and optionally declares or
defines identifiers listed in its associated future library
directions subclause and identifiers which are always
reserved either for any use or for use as file scope
identifiers.

.... snip ...

-- All identifiers with external linkage in any of the
following subclauses (including the future library
directions) are always reserved for use as identifiers
with external linkage.143)
 
F

Flash Gordon

Richard Bos wrote, On 23/03/07 08:17:

Because if you include string.h you are not allowed to define macros
starting with a str followed by a lower case letter, an if you are doing
string operations you are likely to include it.
 
R

Richard Bos

Malcolm McLean said:
"Richard Bos" <[email protected]> wrote in message

[ Please do not over-strip attributions. ]
But there's another qualification for knowing whether C is a "portable
assembly" or not.

That does not make sense. If you know either C or assembly reasonably
well, and the other even superficially, it becomes obvious that C is not
any kind of assembler. No other qualifications are needed.

Richard
 
A

ais523

Malcolm McLean said:
"Richard Bos" <[email protected]> wrote in message

[ Please do not over-strip attributions. ]
But there's another qualification for knowing whether C is a "portable
assembly" or not.

That does not make sense. If you know either C or assembly reasonably
well, and the other even superficially, it becomes obvious that C is not
any kind of assembler. No other qualifications are needed.

Richard

C is of a different nature than assembly language. Still, I sometimes
write C for a particular system envisioning the sort of assembly
language output that it will compile into, whilst knowing that it will
still be portable to other systems. In this sense, C could be
described as 'a portable alternative to assembly language in some
situations'. The term 'portable assembly language' to me conjures up
something a lot more like C-- (<http://www.cminusminus.org/>), which
acts a lot more like assembly language than C (although it still looks
more like C than assembler); but portable assembly is pretty much
impossible, because by the nature of assembly language it's machine-
specific. No, C is not an assembler, and C could not be mistaken for
assembly language; but C shares some of the features that make
assembly language useful (moreso than many other higher-level
languages).
 
M

Malcolm McLean

Richard Bos said:
Malcolm McLean said:
"Richard Bos" <[email protected]> wrote in message

[ Please do not over-strip attributions. ]
But there's another qualification for knowing whether C is a "portable
assembly" or not.

That does not make sense. If you know either C or assembly reasonably
well, and the other even superficially, it becomes obvious that C is not
any kind of assembler. No other qualifications are needed.
Let's say it alleged that a zebra is a "striped horse". There are various
biochemical differences between zerbras and horses, so this is a description
and not a definition. But is it useful?
What you need is an outgroup. If we take donkeys, mules, Eohippus and
unicorns as our outgroups then the description isn't much use. Zebras are
striped, but they are not noticeably more horse-like than these other
animals. However if we take tigers, dogs, and elephants as the outgroups
then the description is of considerable use.

If follows that to have a qualified opinion on whether C is a "portable
assembler" or not you need not only a knowledge of C and assembler, and
portability, but also of the other languages in general use to which C is
being compared.
 
K

Keith Thompson

CBFalconer said:
Keith said:
Yes, it is. C99 7.26.11, under "Future library directions":

Function names that begin with str, mem, or wcs and a lowercase
letter may be added to the declarations in the <string.h> header.

No it isn't. See:

7.1.3 Reserved identifiers

[#1] Each header declares or defines all identifiers listed
in its associated subclause, and optionally declares or
defines identifiers listed in its associated future library
directions subclause and identifiers which are always
reserved either for any use or for use as file scope
identifiers.

... snip ...

-- All identifiers with external linkage in any of the
following subclauses (including the future library
directions) are always reserved for use as identifiers
with external linkage.143)

Is the str_dup() function or the strdup macro that you're saying is
illegal?

str_dup is not a reserved identifier; it doesn't begin with str
and a lowercase letter.

strdup, if defined as a macro, doesn't have external linkage (though
you might need a "#undef strdup" if you've included <string.h>).

In particular, I claim that the following program:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char *str_dup(const char *s)
{
char *result = malloc(strlen(s) + 1);
if (result != NULL) {
strcpy(result, s);
}
return result;
}

#undef strdup
#define strdup(s) str_dup(s)

int main(void)
{
char *s = strdup("hello, world");
if (s == NULL) {
fputs("strdup() failed\n", stderr);
return EXIT_FAILURE;
}
else {
puts(s);
return EXIT_SUCCESS;
}
}

is valid, and that it fails to be strictly conforming only because of
the possibility of failure in the calls to malloc and perhaps puts.
(There's some controversy about whether I/O failures break strict
conformance; I don't want to get into that in this this thread.)

As a matter of style and robust coding, I prefer not to worry about
the details of which identifiers are reserved for which purposes in
which circumstances. It's easier just to avoid all potentially
reserved identifiers in all circumstances than to keep track of all
the rules. Because of that, I wouldn't write the above program in
that way; I'd probably just name the function str_dup or dupstr and
not worry about the macro. (Or I might use strdup if I didn't care
about portability to non-POSIX systems.)
 
C

CBFalconer

Keith said:
.... SNIP ...

strdup, if defined as a macro, doesn't have external linkage (though
you might need a "#undef strdup" if you've included <string.h>).

In particular, I claim that the following program:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char *str_dup(const char *s)
{
char *result = malloc(strlen(s) + 1);
if (result != NULL) {
strcpy(result, s);
}
return result;
}

#undef strdup
#define strdup(s) str_dup(s)

int main(void)
{
char *s = strdup("hello, world");
if (s == NULL) {
fputs("strdup() failed\n", stderr);
return EXIT_FAILURE;
}
else {
puts(s);
return EXIT_SUCCESS;
}
}

is valid, and that it fails to be strictly conforming only because of
the possibility of failure in the calls to malloc and perhaps puts.
(There's some controversy about whether I/O failures break strict
conformance; I don't want to get into that in this this thread.)

Yes, I have to concede that that is legal, as "strdup" never
escapes the confines of the source file. As you mentioned, the
gyrations are pointless, since you can much more easily simply use
an allowable name.
 
J

jaysome

CBFalconer said:
Keith said:
Richard Bos wrote:

Also _because_ it is so easy to write yourself.

Too bad you're not allowed to call it "strdup" if you #include
<string.h> :)

*Shrug* Call it str_dup() and #define strdup str_dup, then.
That's legal.

No it isn't.

Yes, it is. C99 7.26.11, under "Future library directions":

Function names that begin with str, mem, or wcs and a lowercase
letter may be added to the declarations in the <string.h> header.

No it isn't. See:

7.1.3 Reserved identifiers

[#1] Each header declares or defines all identifiers listed
in its associated subclause, and optionally declares or
defines identifiers listed in its associated future library
directions subclause and identifiers which are always
reserved either for any use or for use as file scope
identifiers.

... snip ...

-- All identifiers with external linkage in any of the
following subclauses (including the future library
directions) are always reserved for use as identifiers
with external linkage.143)

Is the str_dup() function or the strdup macro that you're saying is
illegal?

str_dup is not a reserved identifier; it doesn't begin with str
and a lowercase letter.

Although not strictly legal, any identifier that begins with str and a
lowercase letter and includes one or more underscores will never
conflict with any present or future identifier defined by the C
Standard, IMHO.

Neither C90 nor C99 define any identifiers beginning with str and
followed by a lowercase letter that include one or more underscores.
And future C Standards will most likely (99.99999999% probability) not
deviate from this.

The following identifiers will always and forever not conflict with a
C Standard identifier, IMHO:

extern void strip_leading_whitespace(char *s);
extern void strip_trailing_whitespace(char *s);

If and when a future C Standard decides to implement equivalent
functions, they will be named without underscores, e.g.:

extern void strlws(char *s);
extern void strtws(char *s);

I choose to use names like "strip_leading_whitespace" instead of
playing silly games and using silly names like
"Strip_leading_whitespace" or "stp_leading_whitespace". And I don't
hold anything against those who do the same.

Best regards
 
G

Guest

Keith said:
CBFalconer said:
Keith said:
Richard Bos wrote:

Also _because_ it is so easy to write yourself.

Too bad you're not allowed to call it "strdup" if you #include
<string.h> :)

*Shrug* Call it str_dup() and #define strdup str_dup, then.
That's legal.

No it isn't.

Yes, it is. C99 7.26.11, under "Future library directions":

Function names that begin with str, mem, or wcs and a lowercase
letter may be added to the declarations in the <string.h> header.

No it isn't. See:

7.1.3 Reserved identifiers

[#1] Each header declares or defines all identifiers listed
in its associated subclause, and optionally declares or
defines identifiers listed in its associated future library
directions subclause and identifiers which are always
reserved either for any use or for use as file scope
identifiers.

... snip ...

-- All identifiers with external linkage in any of the
following subclauses (including the future library
directions) are always reserved for use as identifiers
with external linkage.143)

Is the str_dup() function or the strdup macro that you're saying is
illegal?

str_dup is not a reserved identifier; it doesn't begin with str
and a lowercase letter.

strdup, if defined as a macro, doesn't have external linkage (though
you might need a "#undef strdup" if you've included <string.h>).

Even if you made sure to undefine any pre-existing strdup macro
definition, if you provide your own, the behaviour is undefined per
7.1.3p2.
 
P

pete

jaysome wrote:
Although not strictly legal, any identifier that begins with str and a
lowercase letter and includes one or more underscores will never
conflict with any present or future identifier defined by the C
Standard, IMHO.

Neither C90 nor C99 define any identifiers beginning with str and
followed by a lowercase letter that include one or more underscores.
And future C Standards will most likely (99.99999999% probability) not
deviate from this.

That's not worth knowing even if it's true.

It's simpler just to know the rules and follow them.
 
K

Keith Thompson

Harald van Dijk said:
Keith said:
CBFalconer said:
Keith Thompson wrote:
Richard Bos wrote:

Also _because_ it is so easy to write yourself.

Too bad you're not allowed to call it "strdup" if you #include
<string.h> :)

*Shrug* Call it str_dup() and #define strdup str_dup, then.
That's legal.

No it isn't.

Yes, it is. C99 7.26.11, under "Future library directions":

Function names that begin with str, mem, or wcs and a lowercase
letter may be added to the declarations in the <string.h> header.

No it isn't. See:

7.1.3 Reserved identifiers

[#1] Each header declares or defines all identifiers listed
in its associated subclause, and optionally declares or
defines identifiers listed in its associated future library
directions subclause and identifiers which are always
reserved either for any use or for use as file scope
identifiers.

... snip ...

-- All identifiers with external linkage in any of the
following subclauses (including the future library
directions) are always reserved for use as identifiers
with external linkage.143)

Is the str_dup() function or the strdup macro that you're saying is
illegal?

str_dup is not a reserved identifier; it doesn't begin with str
and a lowercase letter.

strdup, if defined as a macro, doesn't have external linkage (though
you might need a "#undef strdup" if you've included <string.h>).

Even if you made sure to undefine any pre-existing strdup macro
definition, if you provide your own, the behaviour is undefined per
7.1.3p2.

Yes, you're right, I missed that.

For those who don't have a copy of the standard handy, the cited
paragraph is:

No other identifiers are reserved. If the program declares or
defines an identifier in a context in which it is reserved (other
than as allowed by 7.1.4), or defines a reserved identifier as a
macro name, the behavior is undefined.

So in addition to the limited reservations specified in 7.1.3p1
(certain identifiers being reserved for use at file scope, or as
identifiers with external linkage), *any* identifier that's reserved
for *any* purpose may not be defined as a macro.

Any standard function can be defined as a macro in addition to its
definition as a function. An implementation could define a macro
strfoo, then use the strfoo macro in the definition of its strlen
macro. Undefining and redefining your own strfoo macro would then
break calls to strlen. I don't think this is a likely scenario (an
implementer would be wiser to use a more clearly reserved identifier
such as __strfoo), but it appears to be legal, and I'm sure the DS9K
plays this trick with strdup.

I was wrong about the details, but this reinforces my point that it's
better for a programmer just to avoid *all* reserved identifiers
rather than keeping track of all the rules about what's reserved in
which contexts.
 
G

Guest

Keith said:
Harald van Dijk said:
Keith said:
Keith Thompson wrote:
Richard Bos wrote:

Also _because_ it is so easy to write yourself.

Too bad you're not allowed to call it "strdup" if you #include
<string.h> :)

*Shrug* Call it str_dup() and #define strdup str_dup, then.
That's legal.

No it isn't.

Yes, it is. C99 7.26.11, under "Future library directions":

Function names that begin with str, mem, or wcs and a lowercase
letter may be added to the declarations in the <string.h> header.

No it isn't. See:

7.1.3 Reserved identifiers

[#1] Each header declares or defines all identifiers listed
in its associated subclause, and optionally declares or
defines identifiers listed in its associated future library
directions subclause and identifiers which are always
reserved either for any use or for use as file scope
identifiers.

... snip ...

-- All identifiers with external linkage in any of the
following subclauses (including the future library
directions) are always reserved for use as identifiers
with external linkage.143)

Is the str_dup() function or the strdup macro that you're saying is
illegal?

str_dup is not a reserved identifier; it doesn't begin with str
and a lowercase letter.

strdup, if defined as a macro, doesn't have external linkage (though
you might need a "#undef strdup" if you've included <string.h>).

Even if you made sure to undefine any pre-existing strdup macro
definition, if you provide your own, the behaviour is undefined per
7.1.3p2.

Yes, you're right, I missed that.

For those who don't have a copy of the standard handy, the cited
paragraph is:

No other identifiers are reserved. If the program declares or
defines an identifier in a context in which it is reserved (other
than as allowed by 7.1.4), or defines a reserved identifier as a
macro name, the behavior is undefined.

So in addition to the limited reservations specified in 7.1.3p1
(certain identifiers being reserved for use at file scope, or as
identifiers with external linkage), *any* identifier that's reserved
for *any* purpose may not be defined as a macro.

Hmm. I didn't really notice that before, but that says that
#define isfunny 0
has UB even if said:
Any standard function can be defined as a macro in addition to its
definition as a function. An implementation could define a macro
strfoo, then use the strfoo macro in the definition of its strlen
macro. Undefining and redefining your own strfoo macro would then
break calls to strlen. I don't think this is a likely scenario (an
implementer would be wiser to use a more clearly reserved identifier
such as __strfoo), but it appears to be legal, and I'm sure the DS9K
plays this trick with strdup.

Such tricks would likely break this strictly conforming program:

#include <string.h>
int main(int strfoo, char *strbar[])
{
return strlen("");
}

An implementation-specific mechanism could be used to bypass the
allowable user strfoo definitions, though. A C/C++ compiler might
provide namespaces as an extension in C mode, and then strlen could
call ::strfoo.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top