Velocity Reviews > Portable and ok?

# Portable and ok?

Keith Thompson
Guest
Posts: n/a

 11-02-2005
Jordan Abel <(E-Mail Removed)> writes:
> On 2005-11-02, Flash Gordon <(E-Mail Removed)> wrote:
>> Dick de Boer wrote:
>>> "pemo" <(E-Mail Removed)> wrote in message
>>> news:dkabl0\$hc9\$(E-Mail Removed)...
>>>
>>>>/*
>>>>** input: an integer [value]. In the range. 0 - 15.
>>>>**
>>>>** return: if in range, the character that encodes the value
>>>>** passed as a hex char - else - NULL.
>>>>*/
>>>>char itoh(int n)
>>>>{
>>>> return n < 0 || n > 15 ? NULL : "0123456789ABCDEF"[n];
>>>>}
>>>
>>> For n out of range:
>>> NULL is a pointer, not a char. In this code, the NULL will be
>>> converted to a char, and *if* NULL equals zero, the return value
>>> will be zero. If NULL equals not zero but for instance (void*)-1,

>>
>> Highly unlikely. (void*)0 and ((void*)0) are likely, but (void*)-1 is
>> *very* unlikely. The reason being that (void*)0 is *required* to produce
>> a null pointer, but (void*)-1 is not.

>
> ok, suppose "null pointers are all-bits-1". There's no guarantee that
> converting a null pointer back to an int will yield a 0.

Certainly -- but note that the code we're discussing uses a null
pointer constant, not (necessarily) a null pointer. If the
implementation uses all-bits-1 for null pointers, NULL could still be
defined as 0; it would result in all-bits-1 if converted to a pointer
type, but would still act as a plain integer constant 0 if it's not
converted to a pointer type.

On the other hand, if NULL is defined as ((void*)0), it would *still*
result in all-bits-1 if coverted to a pointer type, but it must
trigger a diagnostic if used as above.

Even if an implementation uses something other than all-bits-zero for
null pointers, that doesn't affect the definition of a null pointer
constant (something that exists only in program source), and it's not
likely to affect the definition of NULL.

I think the OP has two problems. First, he's incorrectly assuming
that NULL refers to a null character rather than a null pointer
constant. Second, he's probably using an implementation that defines
NULL as 0, so it isn't catching the error.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Simon Biber
Guest
Posts: n/a

 11-02-2005
Martin Ambuhl wrote:
> pemo wrote:
> [Repeated from subject line, where it was wrongly tucked away:
> Subject: Portable and ok?]
>
> No, it's not OK. Don't use pointers for integer values even if you have
> every reason to think it will work. Why are you avoiding using 0 when
> you mean 0?

Since the OP doesn't appear to be participating in this thread, allow me
to hazard a guess:

- don't know the difference between a null pointer and a null character

- the teacher said to *never* use literal values

- thought it possible that null may not be zero, better use the macro
to be sure

Unfortunately, in my experience very few teachers accurately teach the
difference between a null pointer, a null pointer constant and a null
character.

--
Simon.

Jordan Abel
Guest
Posts: n/a

 11-02-2005
On 2005-11-02, Simon Biber <(E-Mail Removed)> wrote:
> - the teacher said to *never* use literal values
>
> - thought it possible that null may not be zero, better use the macro
> to be sure

in either of those two cases, the appropriate way would be '\0'

Keith Thompson
Guest
Posts: n/a

 11-02-2005
Jordan Abel <(E-Mail Removed)> writes:
> On 2005-11-02, Simon Biber <(E-Mail Removed)> wrote:
>> - the teacher said to *never* use literal values
>>
>> - thought it possible that null may not be zero, better use the macro
>> to be sure

>
> in either of those two cases, the appropriate way would be '\0'

Um, '\0' is a literal value.

Of course, there's absolutely nothing wrong with using a literal '\0'
where it's appropriate. *If* the teacher said never to use literal
values, it's very bad advice -- but of course we have no direct
evidence that the teacher said so.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Jordan Abel
Guest
Posts: n/a

 11-02-2005
On 2005-11-02, Keith Thompson <(E-Mail Removed)> wrote:
> Jordan Abel <(E-Mail Removed)> writes:
>> On 2005-11-02, Simon Biber <(E-Mail Removed)> wrote:
>>> - the teacher said to *never* use literal values
>>>
>>> - thought it possible that null may not be zero, better use
>>> the macro to be sure

>>
>> in either of those two cases, the appropriate way would be '\0'

>
> Um, '\0' is a literal value.

So is the string he has with the hex digits - there's very little
you can do without literal values of any kind - i think the most
complicated program you can implement is echo.

> Of course, there's absolutely nothing wrong with using a literal
> '\0' where it's appropriate. *If* the teacher said never to use
> literal values, it's very bad advice -- but of course we have no
> direct evidence that the teacher said so.
>

Keith Thompson
Guest
Posts: n/a

 11-03-2005
Jordan Abel <(E-Mail Removed)> writes:
> On 2005-11-02, Keith Thompson <(E-Mail Removed)> wrote:
>> Jordan Abel <(E-Mail Removed)> writes:
>>> On 2005-11-02, Simon Biber <(E-Mail Removed)> wrote:
>>>> - the teacher said to *never* use literal values
>>>>
>>>> - thought it possible that null may not be zero, better use
>>>> the macro to be sure
>>>
>>> in either of those two cases, the appropriate way would be '\0'

>>
>> Um, '\0' is a literal value.

>
> So is the string he has with the hex digits - there's very little
> you can do without literal values of any kind - i think the most
> complicated program you can implement is echo.

Aha, a challenge!

Without using literals, you can easily construct constant expressions
for any integer you like:

static int dummy;
#define ZERO (&dummy!=&dummy)
#define ONE (&dummy==&dummy)
#define TWO (ONE+ONE)
#define THREE (TWO+ONE)
#define FOUR (THREE+ONE)

Character and string literals are a bit more difficult. You can
construct anything you like if you're willing to assume an ASCII
encoding, but that's cheating. I think you can determine the values
of '0' through '9' by looping over the range 0 .. SCHAR_MAX and
checking isdigit(). You can do the same thing for letters by checking
isupper() and islower(); this works for both ASCII and EBCDIC, but not
for any character sets in which the letters aren't in alphabetical
order. (The results won't be constant expressions unless you go to a
*lot* of extra effort.)

fopen() is difficult because the mode argument is usually a string
literal. It doesn't have to be a constant, but I can't think of a
good way to generate an 'r' or 'w' character.

printf(), of course, requires a format string. It can be built up
manually if you can construct the required characters.

Just to be clear (and because I've criticized others for not including
this disclaimer), this is absolutely nothing more than a silly little
intellectual exercise, of no actual use that I can think of. And I

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Jordan Abel
Guest
Posts: n/a

 11-03-2005
On 2005-11-03, Keith Thompson <(E-Mail Removed)> wrote:
> Jordan Abel <(E-Mail Removed)> writes:
>> So is the string he has with the hex digits - there's very little
>> you can do without literal values of any kind - i think the most
>> complicated program you can implement is echo.

>
> Aha, a challenge!
>
> Without using literals, you can easily construct constant expressions
> for any integer you like:

[snip other stuff]

geez - it'd be easier to program in brainf***

Kenneth Brody
Guest
Posts: n/a

 11-03-2005
"Clark S. Cox III" wrote:
>
> On 2005-11-02 07:32:30 -0500, "pemo" <(E-Mail Removed)> said:
>
> > /*
> > ** input: an integer [value]. In the range. 0 - 15.
> > **
> > ** return: if in range, the character that encodes the value
> > ** passed as a hex char - else - NULL.
> > */
> > char itoh(int n)
> > {
> > return n < 0 || n > 15 ? NULL : "0123456789ABCDEF"[n];
> > }

>
> The only part of that that isn't portable is the attempt to convert
> NULL to a char. However, if you were asking about the
> ("0123456789ABCDEF"[n]) part, that's fine. I would rewrite that
> function as:
>
> char itoh(int n)
> {
> return n < 0 || n > 15 ? 0 : "0123456789ABCDEF"[n];
> }

And, for clarity, I would make a minor change:

char itoh(int n)
{
return (n < 0 || n > 15) ? '\0' : "0123456789ABCDEF"[n];
}

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <(E-Mail Removed)>

Kenneth Brody
Guest
Posts: n/a

 11-03-2005
Keith Thompson wrote:
>
> Jordan Abel <(E-Mail Removed)> writes:
> > On 2005-11-02, Simon Biber <(E-Mail Removed)> wrote:
> >> - the teacher said to *never* use literal values
> >>
> >> - thought it possible that null may not be zero, better use the macro
> >> to be sure

> >
> > in either of those two cases, the appropriate way would be '\0'

>
> Um, '\0' is a literal value.
>
> Of course, there's absolutely nothing wrong with using a literal '\0'
> where it's appropriate. *If* the teacher said never to use literal
> values, it's very bad advice -- but of course we have no direct
> evidence that the teacher said so.

And if the teacher really said never use literal values, then you can't
use the literal "0123456789ABCDEF", either. In fact, you couldn't even
use "%x" to pass to sprintf.

Unless you're allow to use

#define MyHexString "0123456789ABCDEF"

But, I guess this depends on how picky the teacher is.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <(E-Mail Removed)>

tedu
Guest
Posts: n/a

 11-03-2005
Keith Thompson wrote:
> fopen() is difficult because the mode argument is usually a string
> literal. It doesn't have to be a constant, but I can't think of a
> good way to generate an 'r' or 'w' character.

const char *r() { return __func__; }