comparing two strcasecmp (stricmp) implementations

P

pete

Jordan Abel wrote:
And stop citing C99 at me, that's
not the standard in effect in 99% of implementations.

Good point!

7.1.3 Reserved identifiers
If the program declares or defines an identifier with the
same name as an identifier reserved in that context
(other than as allowed by 7.1.7), the behavior is undefined.

7.13 Future library directions
The following names are grouped under individual
headers for Convenience.
All external names described below are reserved
no matter what headers are included by the program.

7.13.8 String handling <string.h>
Function names that begin with str, mem,
or wcs and a lowercase letter
(followed by any combination of digits, letters, and underscore)
I still see
"function names" [which refutes your 'could be using it for other
purposes' claim] and '_may_ be added' [which tells me that if they're
NOT added, they're ok to use].

It tells me that function names starting with str are reserved,

"All external names described below are reserved "

and it doesn't say that they're not reserved
when they are not added.

There is no 'could be using it for other purposes' claim.

How does "function names" or anything else for that matter,
translate into permission to make declarations with
reserved identifiers?
 
J

Jordan Abel

It tells me that function names starting with str are reserved,

"All external names described below are reserved "

and it doesn't say that they're not reserved
when they are not added.

There is no 'could be using it for other purposes' claim.

How does "function names" or anything else for that matter,
translate into permission to make declarations with
reserved identifiers?

It either is there or it's not. This is not a program that
unconditionally defines one, this is based on a test to see whether a
particular implementation allows it

Your reading would forbid third-party POSIX-compliance add-ons.
 
P

pete

It either is there or it's not.

The standard is talking about undefined behavior
in terms of what's reserved, not in terms of what's there.
Your reading would forbid third-party POSIX-compliance add-ons.

Maybe.
POSIX isn't ANSI C, is it?
Didn't POSIX.1c redefine errno as a service?
 
D

Dik T. Winter

> > Jordan Abel wrote: ....
> >> I'm saying that if the implementation does not use the identifier for
> >> either of the two purposes it has been reserved for [as determined at
> >> compile-time], then the program is free to use it.
....
> Because it's not a generally reserved identifier, only one that an
> implementation is free to use for a specific purpose. If it is
> determined that it does not use it for that purpose, where does the
> standard say the user is forbidden to use it?

In addition to other problems, I am wondering how you determine
(compile-time) whether some function has been defined in a header
or not. #ifdef works only for macros (it is in the preprocessor,
identifiers of functions are not in it).
 
J

Jordan Abel

The standard is talking about undefined behavior
in terms of what's reserved, not in terms of what's there.

because it's talking about a translation unit in isoltion
Maybe.
POSIX isn't ANSI C, is it?
Didn't POSIX.1c redefine errno as a service?

eh?

posix doesn't define anything that conflicts with ansi c - what are you
on about?
 
J

Jordan Abel

Jordan Abel wrote: ...
I'm saying that if the implementation does not use the identifier for
either of the two purposes it has been reserved for [as determined at
compile-time], then the program is free to use it.
...
Because it's not a generally reserved identifier, only one that an
implementation is free to use for a specific purpose. If it is
determined that it does not use it for that purpose, where does the
standard say the user is forbidden to use it?

In addition to other problems, I am wondering how you determine
(compile-time) whether some function has been defined in a header
or not. #ifdef works only for macros (it is in the preprocessor,
identifiers of functions are not in it).

Attempt to compile a test program using it and see if it works. Put the
result in config.h and #include "config.h"
 
P

pete

Jordan Abel wrote:
eh?

posix doesn't define anything that conflicts with ansi c
- what are you on about?

POSIX.1c redefines errno as a service that
can access the per-thread error
number as follows (ISO/IEC 9945:1-1996, §2.4):

http://www.unix.org/whitepapers/reentrant.html

I don't think that citing whatever it is
you think you know about POSIX,
to validate your beliefs about ANSI C,
is appropriate.
 
D

Dik T. Winter

>
> Attempt to compile a test program using it and see if it works. Put the
> result in config.h and #include "config.h"

That is quite a bit more than "compile-time". And are you sure that your
test will not give you a false negative? I am pretty sure you can not be
confident about that. "autoconf" and "configure" in many cases will fail
to give something that can reliably be compiled and used.
 
J

Jordan Abel

POSIX.1c redefines errno as a service that
can access the per-thread error
number as follows (ISO/IEC 9945:1-1996, §2.4):

http://www.unix.org/whitepapers/reentrant.html

errno is permitted to be a macro. imagine

<errno.h>:
int *__get_this_threads_errno_location();
#define errno (*__get_this_threads_errno_location())
/* or, another possibility */
extern __attribute__((per_thread)) int errno;

how does this contradict ansi?
 
C

Chris Torek

[on whether a program can use the identifiers "strcasecmp" or "stricmp"]
On 2005-11-14, pete <[email protected]> [and in a nested quote
of an earlier article also by pete] wrote [text from the C99 standard
that says using these identifiers in the usual way is in fact undefined.]

It's bad form to followup to yourself. And stop citing C99 at me, that's
not the standard in effect in 99% of implementations.

This wording is essentially unchanged from C89, however.
I still see "function names" [which refutes your 'could be using it
for other purposes' claim] and '_may_ be added' [which tells me that
if they're NOT added, they're ok to use].

There is a practical problem here, and it has in fact occurred in
the past (although I doubt it will occur with either the names
strcasecmp() or stricmp()). That is: several different "popular"
implementations will actually implement functions that have *the
same name* but *different arguments*.

A test that attempts to determine whether strcasecmp() exists might
then find that it does -- but the strcasecmp() that the implementation
provides might take three or four arguments, instead of two.

One would (in such case) be faced with two alternatives in a program
that uses:

#ifndef HAVE_STRCASECMP
int strcasecmp(const char *l, const char *r) { ... code ... }
#endif

One could (a) define HAVE_STRCASECMP, causing the program to use
the implementation's function -- which needs more than two arguments
so the calls do not work -- or (b) leave HAVE_STRCASECMP undefined,
causing the program to define a strcasecmp() that conflicts with
the implementation's function, which may in turn lead the implementation
to crash or otherwise behave badly.

Practically speaking, I doubt that this situation will actually
occur with the name "strcasecmp", as I noted above, it has in fact
occurred before with other functions, the classic example being
"itoa": some implementation-provided itoa() functions take one
argument, some take two, and some take three. (I have never seen
any that take four, although four would actually be reasonable.)
 
K

Keith Thompson

pete said:
POSIX.1c redefines errno as a service that
can access the per-thread error
number as follows (ISO/IEC 9945:1-1996, §2.4):

C99 says that errno

expands to a modifiable lvalue that has type int, the value of
which is set to a positive error number by several library
functions. It is unspecified whether errno is a macro or an
identifier declared with external linkage.
 
K

Keith Thompson

Jordan Abel said:
It's bad form to followup to yourself.

Um, why? I've done it myself a number of times when I've thought of
something after I've posted a message.
 
J

Jordan Abel

Um, why? I've done it myself a number of times when I've thought of
something after I've posted a message.

I guess my statement was based on a somewhat naive belief that supercede
would actually be likely to work - sorry
 
P

pete

I have nothing left from the C standard to show.
I don't really know enough about posix to discuss it.
 
C

Chris Dollin

pete said:
int str_ccmp( const char *s1, const char *s2 )
{
int c1, c2;

do {
c1 = tolower( (unsigned char) *s1++ );
c2 = tolower( (unsigned char) *s2++ );
} while (c1 == c2 && c1 != 0);
return c2 > c1 ? -1 : c1 > c2;
}

I still find the version I posted earlier to be clearer:


int strcasecmp( const char *s1, const char *s2 )
{
while (1)
{
int c1 = tolower( (unsigned char) *s1++ );
int c2 = tolower( (unsigned char) *s2++ );
if (c1 == 0 || c1 != c2) return c1 - c2;
}
}

mostly because the signt of an uninitialised variable makes my
guts ache (and because I see no merit, absent some /specific/
documentation, for working so hard on the return value).

If the scope rules for do/while were more useful, I'd use it;
but they aren't.
 
C

Chris Dollin

pete said:
We all think like that.

That's not the impression I'm getting. By the way, I /did/
supply some reasons /why/; you're not /required/ to comment
on them, of course.
 
M

Mark McIntyre

It's bad form to followup to yourself. And stop citing C99 at me, that's
not the standard in effect in 99% of implementations.

Irrelevant, since C89 had essentially identical wording.
I still see
"function names" [which refutes your 'could be using it for other
purposes' claim] and '_may_ be added' [which tells me that if they're
NOT added, they're ok to use].

Not at all - how can you tell they're not there?
 
J

Jordan Abel

It's bad form to followup to yourself. And stop citing C99 at me, that's
not the standard in effect in 99% of implementations.

Irrelevant, since C89 had essentially identical wording.
I still see
"function names" [which refutes your 'could be using it for other
purposes' claim] and '_may_ be added' [which tells me that if they're
NOT added, they're ok to use].

Not at all - how can you tell they're not there?

The specific mechanism isn't particularly relevant, but in many cases if
a function is not provided by the implementation, or is not declared in
the header, it is possible [either always, or with implementation-specific
options] for the program to fail to translate.
 
M

Michael Wojcik

As function names in stdlib.h and string.h - they are not reserved for
any other purpose, and if it has been determined that the headers in
question don't contain that function name...

Wrong. C90 7.13: "All external names described below are reserved
no matter what headers are included by the program"; 7.13.8: "Function
names beginning with str, ...".
At which point HAVE_STRCASECMP will presumably test true,

Now there's a compelling argument. "This is wrong, but presumably
it'll go away if it might cause a problem." Why not avoid the
problem in the first place?
since these
are generated by seeing if a test program trying to use it successfully
translates.

And you know that how?
It's not allowed to do that. The language of the standard only permits
implementations to use it as a function name, and only in stdlib.h or
string.h. Nowhere else and for no other purpose.

Wrong. The identifier is reserved to the implementation. The
implementation *may* add it to string.h, but need not.

If the implementation does add it to string.h, it need not do what
the OP's function does.
 

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,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top