Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Hex to int

Reply
Thread Tools

Hex to int

 
 
Ben Bacarisse
Guest
Posts: n/a
 
      12-04-2007
James Kuyper <(E-Mail Removed)> writes:

> http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
>> Ben Bacarisse wrote:
>>> (E-Mail Removed) writes:
>>>
>>>> Here is my solution to Exercise 2.3.
>>> <snip>
>>>
>>> I'll comment only on the thing not yet pointed out...
>>>
>>>> int htoi(char *s)
>>>> {
>>>> char *t=s;
>>>> int x=0, y=1;
>>>> if(*s=='0' && (s[1]=='x' || s[1]=='X'))
>>>> t+=2;
>>>> s+=strlen(s);
>>>> while(t<=--s) {
>>> This loop condition is likely to invoke undefined behaviour. Can you
>>> see why?

>>
>> No.

>
> For a string not prefixed by "0x" or "0X", what happens to s if t==s
> at the time the loop condition is evaluated?


Thanks. I was going to get back to this, it just took me a bit of
time...

If the OP needs any more hints: UB occurs whenever the function is
called with a pointer to the start of an object which does not begin
"0x" or "0X". htoi("-32" + 1) and htoi("0x32") are OK, but htoi("32")
is not.

--
Ben.
 
Reply With Quote
 
 
 
 
Lew Pitcher
Guest
Posts: n/a
 
      12-04-2007
On Dec 4, 9:22 am, Ben Bacarisse <(E-Mail Removed)> wrote:
> James Kuyper <(E-Mail Removed)> writes:
> > (E-Mail Removed) wrote:
> >> Ben Bacarisse wrote:
> >>> (E-Mail Removed) writes:

>
> >>>> Here is my solution to Exercise 2.3.
> >>> <snip>

>
> >>> I'll comment only on the thing not yet pointed out...

>
> >>>> int htoi(char *s)
> >>>> {
> >>>> char *t=s;
> >>>> int x=0, y=1;
> >>>> if(*s=='0' && (s[1]=='x' || s[1]=='X'))
> >>>> t+=2;
> >>>> s+=strlen(s);
> >>>> while(t<=--s) {
> >>> This loop condition is likely to invoke undefined behaviour. Can you
> >>> see why?

>
> >> No.

>
> > For a string not prefixed by "0x" or "0X", what happens to s if t==s
> > at the time the loop condition is evaluated?

>
> Thanks. I was going to get back to this, it just took me a bit of
> time...
>
> If the OP needs any more hints: UB occurs whenever the function is
> called with a pointer to the start of an object which does not begin
> "0x" or "0X". htoi("-32" + 1) and htoi("0x32") are OK, but htoi("32")
> is not.


Ben, not meaning to jiggle your elbow, but...

How is
htoi("-32" + 1)
different from
htoi("32");
?

Just trying to understand your point here

 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      12-04-2007
Lew Pitcher <(E-Mail Removed)> writes:

> On Dec 4, 9:22 am, Ben Bacarisse <(E-Mail Removed)> wrote:
>> James Kuyper <(E-Mail Removed)> writes:
>> > (E-Mail Removed) wrote:
>> >> Ben Bacarisse wrote:
>> >>> (E-Mail Removed) writes:

>>
>> >>>> Here is my solution to Exercise 2.3.
>> >>> <snip>

>>
>> >>> I'll comment only on the thing not yet pointed out...

>>
>> >>>> int htoi(char *s)
>> >>>> {
>> >>>> char *t=s;
>> >>>> int x=0, y=1;
>> >>>> if(*s=='0' && (s[1]=='x' || s[1]=='X'))
>> >>>> t+=2;
>> >>>> s+=strlen(s);
>> >>>> while(t<=--s) {
>> >>> This loop condition is likely to invoke undefined behaviour. Can you
>> >>> see why?

>>
>> >> No.

>>
>> > For a string not prefixed by "0x" or "0X", what happens to s if t==s
>> > at the time the loop condition is evaluated?

>>
>> Thanks. I was going to get back to this, it just took me a bit of
>> time...
>>
>> If the OP needs any more hints: UB occurs whenever the function is
>> called with a pointer to the start of an object which does not begin
>> "0x" or "0X". htoi("-32" + 1) and htoi("0x32") are OK, but htoi("32")
>> is not.

>
> Ben, not meaning to jiggle your elbow, but...
>
> How is
> htoi("-32" + 1)
> different from
> htoi("32");
> ?
>
> Just trying to understand your point here


I was not trying to be cute and obscure. Here's my version of the
problem. I hope I have not made a mistake with all this!

In the call htoi("-32" + 1) s points one byte into an object so the
terminating condition of the loop 't <= --s' is met when s points at
the '-'. If the string has no "0x" prefix, the terminating condition
is met when s has been decremented to make a pointer that points
before the start of the object. This, I think, is not allowed.

--s is defined to mean the same as s -= 1 and s -= 1 is defined to
mean the same as s = s - 1 (but the lvalue s is not evaluated twice).
Thus section 6.5.6 (which describes + and -) governs what pointer
arithmetic you can do with --. Paragraph 8 says that the result is
well defined only when the resulting pointer points into, or just
past, the object. You don't have to de-reference the pointer to get
UB -- the arithmetic alone is enough (although * applied to the "just
past the end" pointer is also undefined).

--
Ben.
 
Reply With Quote
 
jameskuyper@verizon.net
Guest
Posts: n/a
 
      12-04-2007
Lew Pitcher wrote:
> On Dec 4, 9:22 am, Ben Bacarisse <(E-Mail Removed)> wrote:

....
> > If the OP needs any more hints: UB occurs whenever the function is
> > called with a pointer to the start of an object which does not begin
> > "0x" or "0X". htoi("-32" + 1) and htoi("0x32") are OK, but htoi("32")
> > is not.

>
> Ben, not meaning to jiggle your elbow, but...
>
> How is
> htoi("-32" + 1)
> different from
> htoi("32");


Trace through the original code; the '-' is recognized as an invalid
character, resulting in an early exit from the loop just one step
before it would otherwise have had undefined behavior.
 
Reply With Quote
 
Lew Pitcher
Guest
Posts: n/a
 
      12-04-2007
On Dec 4, 12:11 pm, Ben Bacarisse <(E-Mail Removed)> wrote:
> Lew Pitcher <(E-Mail Removed)> writes:
> > On Dec 4, 9:22 am, Ben Bacarisse <(E-Mail Removed)> wrote:[snip]
> >> If the OP needs any more hints: UB occurs whenever the function is
> >> called with a pointer to the start of an object which does not begin
> >> "0x" or "0X". htoi("-32" + 1) and htoi("0x32") are OK, but htoi("32")
> >> is not.

>
> > Ben, not meaning to jiggle your elbow, but...

>
> > How is
> > htoi("-32" + 1)
> > different from
> > htoi("32");
> > ?

>
> > Just trying to understand your point here

>
> I was not trying to be cute and obscure. Here's my version of the
> problem. I hope I have not made a mistake with all this!
>
> In the call htoi("-32" + 1) s points one byte into an object so the
> terminating condition of the loop 't <= --s' is met when s points at
> the '-'. If the string has no "0x" prefix, the terminating condition
> is met when s has been decremented to make a pointer that points
> before the start of the object. This, I think, is not allowed.


Thanks, Ben. I knew I was missing something.

--
Lew
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      12-04-2007
(E-Mail Removed) writes:

> Lew Pitcher wrote:
>> On Dec 4, 9:22 am, Ben Bacarisse <(E-Mail Removed)> wrote:

> ...
>> > If the OP needs any more hints: UB occurs whenever the function is
>> > called with a pointer to the start of an object which does not begin
>> > "0x" or "0X". htoi("-32" + 1) and htoi("0x32") are OK, but htoi("32")
>> > is not.

>>
>> Ben, not meaning to jiggle your elbow, but...
>>
>> How is
>> htoi("-32" + 1)
>> different from
>> htoi("32");

>
> Trace through the original code; the '-' is recognized as an invalid
> character, resulting in an early exit from the loop just one step
> before it would otherwise have had undefined behavior.


Not quite. The function copies 's' to 't' and then loops 'while (t <=
--s)' so the inner test for invalid characters never sees the '-' in a
call like htoi("-32" + 1). The +1 simply avoids the UB by passing a
pointer that is not the start of an object. htoi("-32") would avoid
the UB for exactly the reasons you give.

The big point here is that running pointer loops backwards is tricky
and needs extra care because there is no special right to "go off the
end" (even by one) in that direction.

--
Ben.
 
Reply With Quote
 
rajash@thisisnotmyrealemail.com
Guest
Posts: n/a
 
      12-04-2007
James Kuyper wrote:
> For a string not prefixed by "0x" or "0X", what happens to s if t==s at
> the time the loop condition is evaluated?


Then --s will evaluate to the address one before the pointer
originally passed to the function. This would only cause a problem if
the original pointer was to address 0, but in that case it would be a
NULL pointer, which isn't allowed (the argument given to htoi must be
a STRING).
 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      12-04-2007
(E-Mail Removed) wrote, On 04/12/07 19:40:
> James Kuyper wrote:
>> For a string not prefixed by "0x" or "0X", what happens to s if t==s at
>> the time the loop condition is evaluated?

>
> Then --s will evaluate to the address one before the pointer
> originally passed to the function. This would only cause a problem if
> the original pointer was to address 0,


Incorrect. Calculating a pointer to before the object you started in (as
in this case) ALWAYS invokes undefined behaviour. On a lot of
implementations (probably most) it does what the programmer would
expect, but bounds checking implementations that detect this and abort
the program are not only legal but useful.

> but in that case it would be a
> NULL pointer,


Not necessarily true. The null pointer might not be all bits 0 (i.e. an
address or 0) and a pointer with all bits 0 could well be a valid
pointer (i.e. not a null pointer). There are even sensible reasons why
one might do this.

A 0 in the source code used in a pointer context is another matter, and
the implementation has to do whatever magic is required to make it work,
even if that means "int *p = 0;" does not set p to all bits 0.

> which isn't allowed (the argument given to htoi must be
> a STRING).


Actually, it must be a pointer to the first character of a string, but
you were almost correct on this bit
--
Flash Gordon
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      12-04-2007
(E-Mail Removed) writes:
> James Kuyper wrote:
>> For a string not prefixed by "0x" or "0X", what happens to s if t==s at
>> the time the loop condition is evaluated?

>
> Then --s will evaluate to the address one before the pointer
> originally passed to the function. This would only cause a problem if
> the original pointer was to address 0, but in that case it would be a
> NULL pointer, which isn't allowed (the argument given to htoi must be
> a STRING).


No, if the passed pointer points to the beginning of an object (as
opposed to the "-32"+1 example elsethread), then attempting to point
before the beginning of the object invokes undefined behavior. For
example, given:

char *s = "hello";

just evaluating (s-1), even without attempting to dereference it,
invokes UB.

Furthermore, address 0 is not necessarily the same as a null pointer.
(The FAQ, www.c-faq.com, has an entire section on null pointers.)

It may be that some implementations will happen to behave as you say,
but that's not guaranteed by the standard.

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
rajash@thisisnotmyrealemail.com
Guest
Posts: n/a
 
      12-04-2007
Keith Thompson wrote:
> (E-Mail Removed) writes:
> > James Kuyper wrote:
> >> For a string not prefixed by "0x" or "0X", what happens to s if t==s at
> >> the time the loop condition is evaluated?

> >
> > Then --s will evaluate to the address one before the pointer
> > originally passed to the function. This would only cause a problem if
> > the original pointer was to address 0, but in that case it would be a
> > NULL pointer, which isn't allowed (the argument given to htoi must be
> > a STRING).

>
> No, if the passed pointer points to the beginning of an object (as
> opposed to the "-32"+1 example elsethread), then attempting to point
> before the beginning of the object invokes undefined behavior. For
> example, given:
>
> char *s = "hello";
>
> just evaluating (s-1), even without attempting to dereference it,
> invokes UB.


There are two ways to think about pointers. It's true that (s-1) isn't
a "valid" pointer to char, because we don't (necessarily) own the
memory before s.

However, if you think about a pointer as just an address in memory,
then s-1 makes sense - it's just the location in memory before s.

> Furthermore, address 0 is not necessarily the same as a null pointer.
> (The FAQ, www.c-faq.com, has an entire section on null pointers.)
>
> It may be that some implementations will happen to behave as you say,
> but that's not guaranteed by the standard.


I think you are mistaken - I've definitely read that char *p=NULL; and
char *p=0; are completely equivalent.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Difference between int i, j; and int i; int j; arun C Programming 8 07-31-2006 05:11 AM
Hex Color Codes - Hex 6 <=> Hex 3 lucanos@gmail.com HTML 10 08-18-2005 11:21 PM
int main(int argc, char *argv[] ) vs int main(int argc, char **argv ) Hal Styli C Programming 14 01-20-2004 10:00 PM
hex(-5) => Futurewarning: ugh, can't we have a better hex than '-'[:n<0]+hex(abs(n)) ?? Bengt Richter Python 6 08-19-2003 07:33 AM
dirty stuff: f(int,int) cast to f(struct{int,int}) Schnoffos C Programming 2 06-27-2003 03:13 AM



Advertisments