set and reset the least significant bit of a address

O

onsbomma

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
}
 
J

Joona I Palaste

onsbomma said:
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
modifiable address.

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

jacob navia

onsbomma said:
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.
 
P

Peter Nilsson

onsbomma said:
.> 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 said:
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.
 
J

jacob navia

Peter said:
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.
 
J

jacob navia

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

jacob
 
W

Walter Roberson

: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] ?
 
R

Richard Tobin

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
 
K

Keith Thompson

jacob navia said:
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?
 
C

Christian Bau

jacob navia said:
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.
 
F

Flash Gordon

jacob said:
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.
 
J

jacob navia

Christian said:
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?
 
J

jacob navia

Flash said:
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;

?????????
 
J

jacob navia

Richard said:
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.
 
J

jacob navia

Walter said:
: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.
 
J

jacob navia

Keith said:
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
 
M

Mark F. Haigh

jacob said:
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
(e-mail address removed)
 
M

Mark F. Haigh

jacob said:
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
hard to understand about that?

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


Mark F. Haigh
(e-mail address removed)
 
D

Dan Pop

In said:
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.
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
 
N

not

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?
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top