writes:
> Keith Thompson wrote:
>> 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.
It's not a valid pointer because it's outside the object, whether we
"own" the memory or not. The behavior of performing the subtraction
is not defined by the standard. (Behaving as you expect is one
possible consequence of undefined behavior -- arguably the worst,
because it makes it difficult to detect bugs.)
> 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.
But C (which is what we discuss here) doesn't define pointers as just
addresses in memory, and not all machines have the same addressing
structure. Most current machines have a simple linear address space,
and allocate objects within that space, but the C standard is
specifically designed to allow for conforming implementations on
hardware with other schemes.
Segmented architectures are not uncommon. In the extreme, an
implementation could even use a distinct segment for each individual
declared object, and cause a hardware trap if you try to compute an
address outside the object where you started.
See section 4 of the comp.lang.c FAQ, <http://c-faq.com/>.
>> 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.
Yes, they are, but no, I'm not mistaken. Both NULL and 0 are null
pointer constants. (Quibble: NULL is a macro that expands to an
implementation-defined null pointer constant.) When a null pointer
constant is used in a pointer context, it's implicitly converted to a
null pointer, which *may or may not* be represented as all-bits-zero.
For example, if a null pointer is represented as 0xFFFFFFFF, then the
declaration
char *p = 0;
will set p's representation to 0xFFFFFFFF.
See section 5 of the comp.lang.c FAQ.
--
Keith Thompson (The_Other_Keith) <kst->
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"