can a character be negative?

B

bartc

Seebs said:
The vast majority of devices which run code written in C are not x86
devices
running Windows.

By computers he probably meant desktop and laptop PCs, which in the consumer
world still seem to mostly use Windows+x86.

(Ten years ago (when I stopped working), probably 99.9% of my clients used
Windows+x86. The very few with Macs could emulate Windows, but the ones with
Linux were out of luck! You can take it that portability wasn't a high
priority for me.)
 
S

Seebs

By computers he probably meant desktop and laptop PCs, which in the consumer
world still seem to mostly use Windows+x86.
Perhaps!

(Ten years ago (when I stopped working), probably 99.9% of my clients used
Windows+x86. The very few with Macs could emulate Windows, but the ones with
Linux were out of luck! You can take it that portability wasn't a high
priority for me.)

Yeah.

These days, though... I think Macs are about as common as left-handers, gays,
and other instances of "perfectly normal" statistical abnormalities. :)

-s
 
P

Phil Carmody

Chris M. Thomasson said:
Phil Carmody said:
Keith Thompson said:
Rahul wrote:
[...]
2.and in what scenarios should I define a character as unsigned?

You shouldn't. If you know that it is a character, use char. Only use
unsigned char if you're storing numbers rather that characters.

Well, mostly. The is*() and to*() functions in <ctype.h> expect
arguments representable as an unsigned char (or the value EOF).

Wishy-washy-signedness of chars is full of traps - your list isn't
exaustive.

Once can reduce to:



#define xxx_ctype_invoke(f, a) f((unsigned int)a)

#define xislower(a) xxx_ctype_invoke(islower, a)
#define xisupper(a) xxx_ctype_invoke(isupper, a)
/* ... */



?

What language was that post in? Did it in some way address the
points raised in my post?

Yours curiously,
Phil
 
P

Phil Carmody

Eric Sosman said:
Phil said:
Eric Sosman said:
[... lengthy development of trivial transformation ...]

Having said that, you may have sneaked some deliberate mistakes into
the above in order to trick me,

I am less duplicitous than you suppose, and perhaps than
you deserve.
[...] I already understand perfectly well how
a heap works. Quite what gave you the impression otherwise, I know not.

Your own words gave me that impression: "The heap is defined
by the heap property, and [0] doesn't have that property," which
suggests to me that you have at best a muddled idea of how a
heap works.

Your interpretation of the English language is perverse to say the
least.

I'll have what he's having said:
[... concerning the "great" complication of inserting one
addition and one subtraction ...]
Fortunately I don't boggle at the complication, I boggle at the
programmer who would chose that lack of simplicity.

I boggle at the programmer who would reject an algorithm

Bzzzt.

Your failure to understand has been expressed painfully clearly;
no point continuing.

Phil
 
S

Seebs

Have you ever noticed that Macs are _precisely_ as common as
left-handers and gays... . ;-)

Yes, although oddly, I know gay mac users, left-handed mac users, and
left-handed gays, but no left-handed gay mac users.

There is clearly something wrong.

-s
 
P

Phil Carmody

Seebs said:
Yes, although oddly, I know gay mac users, left-handed mac users, and
left-handed gays, but no left-handed gay mac users.

There is clearly something wrong.

Maybe there's a parity check?

Phil
 
T

Tim Rentsch

Ben Bacarisse said:
Chris M. Thomasson said:
Phil Carmody said:
Rahul wrote:
[...]
2.and in what scenarios should I define a character as unsigned?

You shouldn't. If you know that it is a character, use char. Only use
unsigned char if you're storing numbers rather that characters.

Well, mostly. The is*() and to*() functions in <ctype.h> expect
arguments representable as an unsigned char (or the value EOF).

Wishy-washy-signedness of chars is full of traps - your list isn't
exaustive.

Once can reduce to:

#define xxx_ctype_invoke(f, a) f((unsigned int)a)

#define xislower(a) xxx_ctype_invoke(islower, a)
#define xisupper(a) xxx_ctype_invoke(isupper, a)

How does that help? It may just be insufficient coffee, but i can't
see how converting a signed char to a large positive number meets the
requirements imposed by the ctype functions. In fact, it seems to add
another problem if the large unsigned value can't be represented as an
int. That's not UB, but since the conversion can do anything
including raising a signal it is almost as troublesome as UB.

It guards against accidentally forgetting the calling
requirements of the isXXX functions, which specify
taking a character argument that's been converted to (unsigned char)
(and perhaps thence to (int), but that's done automatically
by the calling conversions). Any (char) is representable as
an (unsigned char).

A disadvantage of the above is that it might do the wrong
thing with an EOF value. But there's no absolutely
foolproof way out of that dilemma.
 
B

Ben Bacarisse

Tim Rentsch said:
Ben Bacarisse said:
Chris M. Thomasson said:
Rahul wrote:
[...]
2.and in what scenarios should I define a character as unsigned?

You shouldn't. If you know that it is a character, use char. Only use
unsigned char if you're storing numbers rather that characters.

Well, mostly. The is*() and to*() functions in <ctype.h> expect
arguments representable as an unsigned char (or the value EOF).

Wishy-washy-signedness of chars is full of traps - your list isn't
exaustive.

Once can reduce to:

#define xxx_ctype_invoke(f, a) f((unsigned int)a)

#define xislower(a) xxx_ctype_invoke(islower, a)
#define xisupper(a) xxx_ctype_invoke(isupper, a)

How does that help? It may just be insufficient coffee, but i can't
see how converting a signed char to a large positive number meets the
requirements imposed by the ctype functions. In fact, it seems to add
another problem if the large unsigned value can't be represented as an
int. That's not UB, but since the conversion can do anything
including raising a signal it is almost as troublesome as UB.

It guards against accidentally forgetting the calling
requirements of the isXXX functions, which specify
taking a character argument that's been converted to (unsigned char)
(and perhaps thence to (int), but that's done automatically
by the calling conversions). Any (char) is representable as
an (unsigned char).

I know the /intent/ of the code, it was the /effect/ I was having
trouble with.

Given char c; when char is signed and c holds a negative value,
islower(c) is an error. I think we both agree up to this point. I
think we also agree that islower((unsigned char)c) is safe and
correct.

I am having trouble with islower((unsigned int)c). Surely the
unsigned int that results from this cast might not even be
representable as an int (the type given in the prototype for islower).
Even if this conversion from unsigned int to int passes your
portability requirements, the value is very unlikely to be "an int, the
value of which shall be representable as an unsigned char" as required
by the ctype functions.
 
T

Tim Rentsch

Ben Bacarisse said:
Tim Rentsch said:
Ben Bacarisse said:
Rahul wrote:
[...]
2.and in what scenarios should I define a character as unsigned?

You shouldn't. If you know that it is a character, use char. Only use
unsigned char if you're storing numbers rather that characters.

Well, mostly. The is*() and to*() functions in <ctype.h> expect
arguments representable as an unsigned char (or the value EOF).

Wishy-washy-signedness of chars is full of traps - your list isn't
exaustive.

Once can reduce to:

#define xxx_ctype_invoke(f, a) f((unsigned int)a)

#define xislower(a) xxx_ctype_invoke(islower, a)
#define xisupper(a) xxx_ctype_invoke(isupper, a)

How does that help? It may just be insufficient coffee, but i can't
see how converting a signed char to a large positive number meets the
requirements imposed by the ctype functions. In fact, it seems to add
another problem if the large unsigned value can't be represented as an
int. That's not UB, but since the conversion can do anything
including raising a signal it is almost as troublesome as UB.

It guards against accidentally forgetting the calling
requirements of the isXXX functions, which specify
taking a character argument that's been converted to (unsigned char)
(and perhaps thence to (int), but that's done automatically
by the calling conversions). Any (char) is representable as
an (unsigned char).

I know the /intent/ of the code, it was the /effect/ I was having
trouble with.

Given char c; when char is signed and c holds a negative value,
islower(c) is an error. I think we both agree up to this point. I
think we also agree that islower((unsigned char)c) is safe and
correct.

I am having trouble with islower((unsigned int)c). Surely the
unsigned int that results from this cast might not even be
representable as an int (the type given in the prototype for islower).
Even if this conversion from unsigned int to int passes your
portability requirements, the value is very unlikely to be "an int, the
value of which shall be representable as an unsigned char" as required
by the ctype functions.

Sorry, I completely missed the point of your earlier posting.
Using ((unsigned int)a) rather than ((unsigned char)a), which is
of course what I hallucinated that it said, doesn't lead to a
good result in general. In fact, the most likely result
(considering the number of two's complement systems out there)
will be no different than if the functions were called directly
with no conversion of their arguments (except the conversion
implied by the parameter's type).

Presumably Chris simply made a mistake and meant
to use ((f)( (unsigned char)(a) )) instead.
 
C

Chris M. Thomasson

Tim Rentsch said:
Ben Bacarisse said:
Tim Rentsch said:
Ben Bacarisse <[email protected]> writes:
[...]
I am having trouble with islower((unsigned int)c). Surely the
unsigned int that results from this cast might not even be
representable as an int (the type given in the prototype for islower).
Even if this conversion from unsigned int to int passes your
portability requirements, the value is very unlikely to be "an int, the
value of which shall be representable as an unsigned char" as required
by the ctype functions.

Sorry, I completely missed the point of your earlier posting.
Using ((unsigned int)a) rather than ((unsigned char)a), which is
of course what I hallucinated that it said, doesn't lead to a
good result in general. In fact, the most likely result
(considering the number of two's complement systems out there)
will be no different than if the functions were called directly
with no conversion of their arguments (except the conversion
implied by the parameter's type).

Presumably Chris simply made a mistake and meant
to use ((f)( (unsigned char)(a) )) instead.

Yes. It was a typo. Sorry about that.
 
D

Dik T. Winter

> Most of the compilers I've used have char signed, but I've used
> several where it's unsigned (several Cray systems, SGI Irix, IBM AIX).
> And char is almost certainly signed on any EBCDIC-based system.

Should be unsigned. (EBCDIC has standard characters with the high bit
set.)
 
K

Keith Thompson

Dik T. Winter said:
Should be unsigned. (EBCDIC has standard characters with the high bit
set.)

Yes, that was a typo, noticed and acknowledged several days ago.
 
D

Dik T. Winter

> (Ten years ago (when I stopped working), probably 99.9% of my clients used
> Windows+x86. The very few with Macs could emulate Windows, but the ones with
> Linux were out of luck! You can take it that portability wasn't a high
> priority for me.)

Not so very long ago the vast majority of desktops at my institute were
running some form of Unix (Irix, Solaris, Linux and whatever). It is only
the last few years that the portion of Windows machines is increasing.
 
R

Richard Bos

Dik T. Winter said:
Not so very long ago the vast majority of desktops at my institute were
running some form of Unix (Irix, Solaris, Linux and whatever).

Yeah, but that's the CWI. That's hardly your average business, or even
your average institution. You're talking about people who _know_
computers, here, not about people who merely use them a lot.

Richard
 

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

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,173
Latest member
GeraldReund
Top