Re: <ctype.h> toLower()

From: Richard Heathfield (dontmail_at_address.co.uk.invalid)
Date: 11/23/03


Date: Sun, 23 Nov 2003 09:21:38 +0000 (UTC)

ellie fant wrote:

>> > I don't need to [link the standard library].
>>
>> Yes, you do, if you want your programs to use anything at all from the
>> standard library.
>
> I don't

Yes, you do. The fact that you don't realise this doesn't change reality in
the slightest degree.

> my compiler must do it automatically , I simply include a header
> and then use the functions.

Your /linker/ does it automatically, not your compiler.

>> > So what is the output from your compiler if it's not a TU,
>>
>> The output of a compiler is generally called an object file. The
> translation
>> unit is the input, not the output.
>
> No I think your wrong ,

That doesn't change the fact that I'm right.

> an obj file output by a compiler is a TU.

Incorrect. See the C Standard.

> obj file and TU are the same thing but a TU can also be a lib file

Incorrect. See the C Standard.

>> > and why do you
>> > think the 384 element array does not exist in this TU?
>>
>> It's in the standard library, the relevant parts of which will be linked
> to
>> my program at the appropriate time.
>
> So if you create an Obj-file/TU/ lib/dll/exe whatever you might be
> creating and your code includes your implementations tolower function then
> you don't think that Obj-file/TU/lib/dll/exe will contain this 384 element
> array? Of course it does.

The exe does, yes. So what?

>> > But you said it was portable, surely portable means it can be ported to
>> > all other environments.
>>
>> Yes; a call to tolower() is a call to tolower(), irrespective of how
>> tolower() is implemented. That's the point.
>
> A call to tolower() with no implementation is undefined.

Nonsense. It is defined by the C standard.

"4.3.2.1 The tolower function

<snip>

   The tolower function converts an upper-case letter to the
corresponding lower-case letter.

Returns

   If the argument is an upper-case letter, the tolower function
returns the corresponding lower-case letter if there is one; otherwise
the argument is returned unchanged. In the C locale, tolower maps
only the characters for which isupper is true to the corresponding
characters for which islower is true."

>> > If you rely on your implementations decision, then you have you lost
>> > the ability to think for yourself?
>>
>> No, I have gained the ability to convert to lower case correctly on any
>> platform, without even having to know which character set is used on that
>> platform.
>
> No you have gained the ability to call a function which may be undefined.

Nonsense. The function's behaviour is well-defined.

>> > Why don't you decide what is best implementation after all you know
>> > what the target platform is , your compiler doesn't.
>>
>> You have that precisely the wrong way around. My compiler knows what its
>> target platform is. I don't necessarily know on which platforms my code
>> will be used. In fact, several people have told me that they have
>> (successfully) used my code on platforms I didn't even know existed.
>
> Well that's just luck it's nothing to do with good design or your
> knowledge of the C language.

"In my experience, there's no such thing as luck." - Obi-Wan Kenobi

>> > I think the code this compiler makes is ok, it's
>> > only you and a handfull other half wits who thinks its wrong.
>>
>> Provided it is used correctly, it's fine for ***your platform***. You
> can't
>> rely on its working on ***other*** platforms.
>
> It's fine for the platform which is was designed for, but you can't rely
> on any code working on all other platforms.

Wrong. *YOU* can't. I can, because I write it that way.

> All code is designed for a specific platform

Wrong. A huge amount of the code I write is designed to work on any
conforming hosted implementation. Your inability to conceive of this
reality does not change the fact that my code works portably, and it works
by design, not by luck.

> if you choose to select a
> list of platforms that you consider important and say your code is
> portable because it works on *your* choice of platforms then fine but that
> doesn't make your code portable, its only your idea of portable. And if I
> choose to write code that is designed for a specific platform you cannot
> say it is wrong because it does not work on all platforms.

It is sometimes necessary to write code that is not portable. This was not
one of those occasions.

>> Non-portable code is sometimes necessary, but always undesirable if a
>> satisfactory portable equivalent can be found. Probably in the region of
>> 90% (for some random but high value of 90) of the C code I write is
>> portable to any hosted implementation, and a good deal of freestanding
>> implementations too. The inability or unwillingness of other people to
>> write portable code does not imply that writing portable code is a bad
>> thing to attempt.
>
> No 90% of your code is NOT portable to any hosted C platform.

Please provide evidence to back up that assertion, which I believe to be
false.

>> >> > You seem to mean shifting source code from one compiler to another.
>> >> > :-s
>> >>
>> >> That's *precisely* what I mean. I expect my code to compile and work
>> >> correctly under gcc, C/370 and LE/370, CodeWarrior, Visual C, lcc,
>> >> Borland C, HiSoft C, EiC, and any other conforming C compiler you care
> to
>> >> mention.
>
> What about this one :
>
http://www.microchip.com/download/tools/picmicro/program/picstart/51034h.pdf
>
> Your code won't work on that compiler because you use implementation
> specific functions?

If it's a hosted environment, and if the compiler conforms to the Standard,
my code will run on it.

>> > But that's not what people mean when they talk about portable software.
>>
>> Yes, it is.
> I disagree.

Your disagreement is noted, but the fact that you have a different meaning
of "portable" than everybody else says more about you than it does about
the meaning of the word.

>> > This is the meaning of portable software, not your idea of moving
>> > source code between compilers:-s
>>
>> So are you telling me that, to write a portable C program, you write the
>> code in C, compile it in Visual Studio, and then transfer the resulting
>> executable binary image to the target machine? Is that really what you
>> believe?
>
> No I am disputing your whole concept of portable software.

All right, dispute it to your heart's content, but please don't bother
disputing it with me, or with any other software professional. We're busy
people. Please find some people at your school or college to dispute with
instead.

<snip>

>> > Here he goes again with his interpreteation of portable <sigh>
>> > Even if it is not portable it still doesn't mean it's wrong
>>
>> As long as it's used correctly, it's fine for that platform. But not
>> necessarily for other platforms.
>
> This reality of all computer programs , they are designed for a specific
> platform.

Interesting. So tell me - for which specific platform is this program
designed?

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

int main(int argc, char **argv)
{
  int rc = EXIT_FAILURE;
  if(argc > 1)
  {
    FILE *fp = fopen(argv[1], "w");
    if(fp != NULL)
    {
      int ch;
      while((ch = getchar()) != EOF)
      {
        putchar(ch);
        putc(ch, fp);
      }
      if(!ferror(stdout) && !ferror(fp))
      {
        rc = EXIT_SUCCESS;
      }
      fclose(fp);
    }
  }
  return rc;
}

>> > as I keep
>> > telling you 99% of all working code is not portable.
>>
>> Certainly the vast majority of working code I produce is portable, so I
>> think you're wrong here.
>
> Even talking about portability in concept of porting source code across
> compilers you are probably wrong to state that your code is portable
> because you use implementation specific functions.

It is true that some of my code uses functions specific to a particular
implementation. Such code is not portable, obviously.

But most of my code does not do that, and that code /is/ portable.

> It is not a requirement that all compilers provide definitions for
> identifiers such as tolower I don't think and this would need to be the
> case to make your code portable.

If the compiler is a hosted implementation which conforms to the C standard,
it *must* provide an implementation of tolower().

> here's another compiler that your code will probably fail on:
> http://www.rentron.com/C2C.htm

If it's a conforming hosted implementation, the vast majority of my code
will work on it. If not, then it isn't a conforming hosted implementation.

I can say this without even looking at the page you cite. This is the whole
point of portable programming. I don't need to know the target platform. I
need only know that it provides a conforming hosted implementation.

>> > So your reason for saying it is wrong is wrong. :-s
>>
>> No, you just don't understand the reason.
> I do understand your reason I just disagree with it.

Well, I can't do anything about your failure to agree with common sense.

>> >> > Here is the code again?
>> >> > #define _tolower(_c) ( (_c)-'A'+'a' )
>> >> >
>> >> > Now are you saying there is something wrong with it or not?
>> >> > :-)
>> >>
>> >> Yes, there are three things wrong with it. Firstly, it begins
>> >> with a leading underscore so I'm suspicious of it immediately
>> >> (because it shows that we're
>> >> dealing with an implementation-specific feature).
>> > No leading underscores are legal, there's nothing wrong with that.
>>
>> Yes, it is legal for the implementation to use identifiers beginning with
>> leading underscores. That's what I said. Duh.
> But you have just written in black and white that one of the things wrong
> with it was the leading underscore

Right. It's not an error for the implementation to define such a macro. It
is, however, an error in portability for me to *call* that macro.

>> >> Secondly, the code itself
>> >> is not portable.
>> > There is no requirement in the C standards for code to be portable(in
> the
>> > way you use it).
>>
>> No, there isn't. There isn't any requirement in the C standard for you to
>> write working code, or even to write any code at all.
> Well that makes your 2nd point invalid then.

No, it merely means you don't understand my second point.

>> >> Thirdly, it doesn't handle non-upper-case characters correctly.
>> > But it's designed only to handle upper case characters, if you write a
>> > piece of code to handle whole numbers you can't say it's wrong because
> it
>> > doesn't handle fractions. So your third point is nonsense as well as
>> > the other two
>>
>> Please stay focused. I was explaining why I wouldn't use the function. I
> see
>> no reason to use a _tolower() routine that can't handle non-upper-case
>> characters when I can use a tolower() routine that is guaranteed to
>> handle them properly.
> The point isn't whether or not you would use the function , the point is
> whether or not the function is correct.

The function works on its platform (I presume). It most certainly does not
work on all platforms. To call it from code that is intended to be portable
would be disastrous.

> If you were to use your imagination a bit you would realise how simple it
> is to impliment that in such a way that it does handle non-upper-case
> characters. As you said earlier wrapping it in an isupper() function may
> be one way of doing this.

You would actually wrap it in an if, but yes, you're right. But hey! I just
had a great idea! Why not use tolower() instead???

>> > <snip>
>> > You just said it was incorrect on 3 points but then you go on to say
> .."
>> > but If they decide to implement it it's fine by me."
>>
>> I gave you three reasons why I wouldn't call it. I am perfectly happy to
>> call VC's tolower() function, and what that does under the hood is
> entirely
>> up to Microsoft, as long as the effect is precisely what the Standard
>> requires.
> But I didn't ask for reasons why you wouldn't use it, I asked if there was
> something wrong with the code.

There is. It's implementation-specific code, the technique it uses is not
portable, and it doesn't work for non-upper-case characters. Those are all
flaws, from the perspective of a C programmer writing portable code.

>> > You want the best of both worlds don't you , you want to criticise it
>> > to death but you still have to say it's ok because everyone knows it's
>> > microsofts code and it's well tried and tested and that it's good legal
>> > standard compliant code.
>>
>> I do indeed want the best of both worlds, and I can /have/ the best of
> both
>> worlds by calling tolower() instead of _tolower().
>
> But tolower is just an identifier it may be undefined.

No, its meaning is carefully defined by an international Standard.

>> > But YOU think it's wrong on 3 points
>>
>> Actually, I merely gave three reasons why I wouldn't call it myself. I
> have
>> no problem with an implementation of tolower() calling _tolower() if
> that's
>> what it thinks is the best way to provide the conversion, /provided/ the
>> tolower() implementation behaves according to spec.
>>
> It's the programmer who wrote the code that decides upon the best way to
> provide the conversion not the function itself.

I failed to parse that.

-- 
Richard Heathfield : binary@eton.powernet.co.uk
"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

Quantcast