# set and reset the least significant bit of a address

Discussion in 'C Programming' started by onsbomma, Mar 15, 2005.

1. ### onsbommaGuest

I want to set and reset the least significant bit of a address (where a
pointers points to).
I tried this, but it is not correct:

#define BIT 0x1

void foo(){
void *p;
*p = *p & ~BIT
}

onsbomma, Mar 15, 2005

2. ### Joona I PalasteGuest

onsbomma <> scribbled the following:
> I want to set and reset the least significant bit of a address (where a
> pointers points to).
> I tried this, but it is not correct:

> #define BIT 0x1

> void foo(){
> void *p;
> *p = *p & ~BIT
> }

Actually, & ~BIT is indeed the right way to reset the LSB. | BIT is the
right way to set it. What you're doing wrong is using p as a void
pointer. A void pointer is only a pointer - it doesn't have any
information of what it's pointing to. You have to use a pointer to an
integer type instead. Oh, and make sure it's actually pointing at a

--
/-- Joona Palaste () ------------- Finland --------\
\-------------------------------------------------------- rules! --------/
"And according to Occam's Toothbrush, we only need to optimise the most frequent
instructions."
- Teemu Kerola

Joona I Palaste, Mar 15, 2005

3. ### jacob naviaGuest

onsbomma wrote:
> I want to set and reset the least significant bit of a address (where a
> pointers points to).
> I tried this, but it is not correct:
>
>
> #define BIT 0x1
>
> void foo(){
> void *p;
> *p = *p & ~BIT
> }

1)
If you want to change the value of the pointer and not the value
of the object being pointed to DO NOT use the "*".

2) convert the pointer value into an unsigned integer capable
of storing a pointer. There is a predefined type for that: intptr_t.

3)
#include <stdint.h>
void *p;
intptr_t ip = (intptr_t)p; // Store the pointer value in ip
ip = ip & ~1; // eliminate the least significant bit
p = (void *)ip; // store the result into the pointer again.

4) Do not write:

p = (void *)((intptr_t)p)&~1;

because in 2 weeks you yourself will be wandering what
that mess means. Write clearly.

jacob navia, Mar 15, 2005
4. ### Peter NilssonGuest

> onsbomma wrote:
>.> I want to set and reset the least significant bit of a address
>.> (where a pointers points to).
>.> I tried this, but it is not correct:
>.>
>.> #define BIT 0x1
>.>
>.> void foo(){
>.> void *p;
>.> *p = *p & ~BIT

Ignoring that p is not initialised, dereferencing a void pointer
is a constraint violation. Use a pointer to unsigned char if you
want to modify a byte.

jacob navia wrote:
> 1)
> If you want to change the value of the pointer and not the value
> of the object being pointed to DO NOT use the "*".
>
> 2) convert the pointer value into an unsigned integer capable
> of storing a pointer. There is a predefined type for that:
> intptr_t.

However it is only available under C99 and it is optional as to
whether an implementation defines it.

> 3)
> #include <stdint.h>
> void *p;
> intptr_t ip = (intptr_t)p; // Store the pointer value in ip
> ip = ip & ~1; // eliminate the least significant bit
> p = (void *)ip; // store the result into the pointer again.

The conversion to and from intptr_t is implementation defined.
This method may well fail to do what's expected on some (real)
machines.

> 4) Do not write:
>
> p = (void *)((intptr_t)p)&~1;

Indeed. ITYM: p = (void *) ( ((intptr_t) p) & ~ (intptr_t) 1 );

> because in 2 weeks you yourself will be wandering what
> that mess means.

I'd be puzzled seeing step 3 anyway.

It would seem simpler to keep track of whether p is at an odd or
even byte and simply use -- where appropriate.

--
Peter

Peter Nilsson, Mar 15, 2005
5. ### jacob naviaGuest

Peter Nilsson wrote:
> The conversion to and from intptr_t is implementation defined.
> This method may well fail to do what's expected on some (real)
> machines.
>

The C standard says (page 256)
<<
The following type designates a signed integer type with the
property that any valid pointer to void can be converted to
this type, then converted back to pointer to void,
and the result will compare equal to the original pointer:

intptr_t

<<

1) It is *not* optional.
2) If it fails to do what is specified this is a broken
implementation.

The current C standard is C99. Of course there are people
that want to destroy C and make it go back to 1969
when it didn't exist. I hope you are not one of them.

What I fail to understand are the people that always
speak about "Standard C" but they mean some inexistent
standard. The C89 Standard doesn't exist any more.

It was replaced by the current one.

jacob navia, Mar 15, 2005
6. ### jacob naviaGuest

You are right, the intptr_t is optional. Sorry.
In the other post I stated that they weren't.

jacob

jacob navia, Mar 15, 2005
7. ### Walter RobersonGuest

In article <42376483\$0\$837\$>,
jacob navia <> wrote:
:The current C standard is C99. Of course there are people
:that want to destroy C and make it go back to 1969
:when it didn't exist. I hope you are not one of them.

:What I fail to understand are the people that always
:speak about "Standard C" but they mean some inexistent
:standard. The C89 Standard doesn't exist any more.

:It was replaced by the current one.

Tell me, did your house / apartment stop existing when they
last revised the relevant Construction Code [e.g., required
that certain kinds of nails be 1mm thicker] ?
--
Beware of bugs in the above code; I have only proved it correct,
not tried it. -- Donald Knuth

Walter Roberson, Mar 15, 2005
8. ### Richard TobinGuest

In article <42376483\$0\$837\$>,
jacob navia <> wrote:
>What I fail to understand are the people that always
>speak about "Standard C" but they mean some inexistent
>standard. The C89 Standard doesn't exist any more.

Standards are for our benefit, not the standards bodies'. If we
continue to use C89, it still exists.

-- Richard

Richard Tobin, Mar 15, 2005
9. ### Keith ThompsonGuest

jacob navia <> writes:
[...]
> The current C standard is C99. Of course there are people
> that want to destroy C and make it go back to 1969
> when it didn't exist. I hope you are not one of them.

That's nonsense, as you should know if you've been paying any
attention at all in this newsgroup.

> What I fail to understand are the people that always
> speak about "Standard C" but they mean some inexistent
> standard. The C89 Standard doesn't exist any more.

My copy of it certainly exists.

> It was replaced by the current one.

Yes, the C90 standard was officially superseded by the C99 standard,
but there are still numerous implementations that conform reasonably
well to the C90 standard, and relatively few that conform to the C99
standard. Given that reality, it's perfectly reasonable to continue
discussing C90, however much we might wish (or not) that C99 had
achieved universal coverage.

That does not in any way constitute wanting to destroy C.

You're complaining about someone mentioning that intptr_t is specific
to C99. Would you prefer that we post answers that assume everyone
has a C99 compiler, so they can come back and ask us what's wrong when
it doesn't work with their C90 compilers?

--
Keith Thompson (The_Other_Keith) <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.

Keith Thompson, Mar 15, 2005
10. ### Christian BauGuest

In article <42376483\$0\$837\$>,
jacob navia <> wrote:

> Peter Nilsson wrote:
> > The conversion to and from intptr_t is implementation defined.
> > This method may well fail to do what's expected on some (real)
> > machines.
> >

>
> The C standard says (page 256)
> <<
> The following type designates a signed integer type with the
> property that any valid pointer to void can be converted to
> this type, then converted back to pointer to void,
> and the result will compare equal to the original pointer:
>
> intptr_t
>
> <<
>
> 1) It is *not* optional.

To quote the C99 Final Draft:

7.18.1.4 Integer types capable of holding object pointers

1 The following type designates a signed integer type with the property
that any valid pointer to void can be converted to this type, then
converted back to pointer to void, and the result will compare equal to
the original pointer:

intptr_t

The following type designates an unsigned integer type with the property
that any valid pointer to void can be converted to this type, then
converted back to pointer to void, and the result will compare equal to
the original pointer:

uintptr_t

These types are optional.
=========================

> 2) If it fails to do what is specified this is a broken
> implementation.

Apparently not.

> The current C standard is C99. Of course there are people
> that want to destroy C and make it go back to 1969
> when it didn't exist. I hope you are not one of them.
>
> What I fail to understand are the people that always
> speak about "Standard C" but they mean some inexistent
> standard. The C89 Standard doesn't exist any more.
>
> It was replaced by the current one.
>
>

Christian Bau, Mar 16, 2005
11. ### Flash GordonGuest

jacob navia wrote:
> Peter Nilsson wrote:
>
>> The conversion to and from intptr_t is implementation defined.
>> This method may well fail to do what's expected on some (real)
>> machines.
>>

>
> The C standard says (page 256)
> <<
> The following type designates a signed integer type with the
> property that any valid pointer to void can be converted to
> this type, then converted back to pointer to void,
> and the result will compare equal to the original pointer:
>
> intptr_t
>
> <<
>
> 1) It is *not* optional.
> 2) If it fails to do what is specified this is a broken
> implementation.

Has this changed from N869 then, which goes on to say "These types are
optional." ?

> The current C standard is C99. Of course there are people
> that want to destroy C and make it go back to 1969
> when it didn't exist. I hope you are not one of them.

Wanting people to know that almost all compilers do not support the
latest standard is not the same as wanting the language to die.

> What I fail to understand are the people that always
> speak about "Standard C" but they mean some inexistent
> standard. The C89 Standard doesn't exist any more.
>
> It was replaced by the current one.

Unless someone has gone around deleting all copies of the old standard
it still exists. It just is not the official current standard, only the
standard that actually is implemented.

Since, as you have been told before, we deal with portable C it is
important to know which version of the standard is applicable when it is
not the most commonly implemented one.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.

Flash Gordon, Mar 16, 2005
12. ### jacob naviaGuest

Christian Bau wrote:
>>2) If it fails to do what is specified this is a broken
>> implementation.

>
>
> Apparently not.
>

Very easy.

Just say

"apparently not".

Not that you would bother to give any
ARGUMENTS why intptr_t would be OK when not doing what
it should do or in which machine/implementation that
doesn't work.

Maybe in a ternary machine using 45.87bits per byte
where sizeof char is 7.9 that would not work isn't it?

jacob navia, Mar 16, 2005
13. ### jacob naviaGuest

Flash Gordon wrote:
> Unless someone has gone around deleting all copies of the old standard
> it still exists. It just is not the official current standard, only the
> standard that actually is implemented.
>

Of course you and the old standard exist.
I wouldn't discuss that.

But "standard C" then, makes no sense.

You want YOUR particular view of the standard, as you would like
it to be.

When implementing the extensions of lcc-win32 I cared to
remain compatible with the standard. But when I discuss them
a holy alliance of people like you start crying

"Standard C, Standard C"

Now, the same people write:

The standard is what I want it to be. I will use this
standard, that standard, etc.

> Since, as you have been told before, we deal with portable C it is
> important to know which version of the standard is applicable when it is
> not the most commonly implemented one.

Ahh not standard C but portable C.

OK. Then how would you implement portably

<inttype> p = (void *)p;

?????????

jacob navia, Mar 16, 2005
14. ### jacob naviaGuest

Richard Tobin wrote:
> In article <42376483\$0\$837\$>,
> jacob navia <> wrote:
>
>>What I fail to understand are the people that always
>>speak about "Standard C" but they mean some inexistent
>>standard. The C89 Standard doesn't exist any more.

>
>
> Standards are for our benefit, not the standards bodies'. If we
> continue to use C89, it still exists.
>

Of course. It is not standard C though.

It is obsolete C.

But you are free to use it. Microsoft Corp has the same
view.

jacob navia, Mar 16, 2005
15. ### jacob naviaGuest

Walter Roberson wrote:
> In article <42376483\$0\$837\$>,
> jacob navia <> wrote:
> :The current C standard is C99. Of course there are people
> :that want to destroy C and make it go back to 1969
> :when it didn't exist. I hope you are not one of them.
>
> :What I fail to understand are the people that always
> :speak about "Standard C" but they mean some inexistent
> :standard. The C89 Standard doesn't exist any more.
>
> :It was replaced by the current one.
>
> Tell me, did your house / apartment stop existing when they
> last revised the relevant Construction Code [e.g., required
> that certain kinds of nails be 1mm thicker] ?

If the construction code changed the standards for nails
and my appartment has the old nails, my appartment is then
NOT STANDARD, and when I sell it, or for the insurance claims
I am supposed to change the nails.

Of course I can go on living in my house without bothering about
standards. Only if I got a problem, the insurance could argue that
I was using a non-standard nail size and if my roof collapses
that is not covered by their contract.

jacob navia, Mar 16, 2005
16. ### jacob naviaGuest

Keith Thompson wrote:
> You're complaining about someone mentioning that intptr_t is specific
> to C99. Would you prefer that we post answers that assume everyone
> has a C99 compiler, so they can come back and ask us what's wrong when
> it doesn't work with their C90 compilers?

You are to a certain point right. I should have mentioned this in my answer.

What I fail to understand are the vague suppositions like:

"It may not work in some machines", without any qualifiers.

Besides, this stuff starts to become a self-fullfiling
prophecy. If everyone says the C99 standard is dead, it may
very well be.

It is implemented in several compilers. You can have under
linux gcc, and under windows you get lcc-win32 or Intel,
as far as I know. So, for many desktops machines this can
be solved. For the embedded systems this is another story.

jacob

jacob navia, Mar 16, 2005
17. ### Mark F. HaighGuest

jacob navia wrote:
> Christian Bau wrote:
> >>2) If it fails to do what is specified this is a broken
> >> implementation.

> >
> >
> > Apparently not.
> >

>
> Very easy.
>
> Just say
>
> "apparently not".
>
> Not that you would bother to give any
> ARGUMENTS why intptr_t would be OK when not doing what
> it should do or in which machine/implementation that
> doesn't work.
>

Now, now, let's take a deep breath, and quit being so hostile.
*Apparently* an implementation that does not define intptr_t is *not*
broken.

Thus, "Apparently not". Capische? Is that so terrible?

> Maybe in a ternary machine using 45.87bits per byte
> where sizeof char is 7.9 that would not work isn't it?

No need to get uppity. Christian's regular and generally accurate
posts are undeserving of your sarcastic disregard.

Mark F. Haigh

Mark F. Haigh, Mar 16, 2005
18. ### Mark F. HaighGuest

jacob navia wrote:
> Flash Gordon wrote:
> > Unless someone has gone around deleting all copies of the old

standard
> > it still exists. It just is not the official current standard, only

the
> > standard that actually is implemented.
> >

>
> Of course you and the old standard exist.
> I wouldn't discuss that.
>
> But "standard C" then, makes no sense.

<snip>

Yeah, it does. "Foo" is valid C89. "Bar" is valid C99. What's so

In theory you may be right. In practice, it's nowhere near as
difficult as you make it out to be.

Mark F. Haigh

Mark F. Haigh, Mar 16, 2005
19. ### Dan PopGuest

In <4237e5b1\$0\$11678\$> jacob navia <> writes:

>Flash Gordon wrote:
>> Unless someone has gone around deleting all copies of the old standard
>> it still exists. It just is not the official current standard, only the
>> standard that actually is implemented.
>>

>
>Of course you and the old standard exist.
>I wouldn't discuss that.
>
>But "standard C" then, makes no sense.

What you fail to realise is that "standard C" has a context-dependent
meaning, because the *relevant* C standard is different in different
contexts. There is no question that the relevant C standard for
comp.std.c is C99. OTOH, c.l.c is dedicated to portable programming
in the real world, where the C99 standard is still a pipe dream (with
insignificant exceptions).

Furthermore, optional C99 features cannot be used in portable C99
programs, either.

>> Since, as you have been told before, we deal with portable C it is
>> important to know which version of the standard is applicable when it is
>> not the most commonly implemented one.

>
>Ahh not standard C but portable C.

It is adherence to a C standard that makes C code portable.

>OK. Then how would you implement portably
>
> <inttype> p = (void *)p;
>
>?????????

By issuing the diagnostic *required* by the (C89/C99) standard.

BTW, implementations need not be portable (and I'm not aware of
any portable implementations, merely of implementations that can be
easily ported).

Dan
--
Dan Pop <>

Dan Pop, Mar 16, 2005
20. ### Guest

On Wed, 16 Mar 2005 08:52:17 +0100, jacob navia <>
wrote:

>When implementing the extensions of lcc-win32 I cared to
>remain compatible with the standard. But when I discuss them
>a holy alliance of people like you start crying

May I ventura a thought here...

Yes, compilers, languages, even some user stuff, should be held to something
of a standard. But shouldn't that standard be a _minimum_ instead of an
exact target? If we all adhere to C-89 where's the growth and improvement
in the language and, by extension, our code? It makes far more sense to me
for compiler writers (and I'm not one) to push the limits always seeking
newer and better ways of doing things. So long as that minimum standard is
met, what's the problem?

For example... I would love to see a C implementation (not c++ or C#...
basic C99) with real string variables. And why not? So long as the
compiler meets some agreed minimum standard, what's wrong with going beyond
that?

, Mar 16, 2005