is possible to build some pointer array?

O

Old Wolf

To sum up:

1. Not all pointers are created equal.
2. Void and char pointers are compatible due to historical reasons.
3. Void pointers can point to anything.

They can't point to functions. Although it is a very common
extension (eg. POSIX includes it) to allow void pointers to point
to functions.
4. Typed pointers can point to void objects only if the object is
properly aligned to not need the extra information contained in the
void pointer. That is, it only needs the 'base address'.

There are no "void objects", and a void pointer need not have
"extra information" (it could just be extra non-useful junk),
and 'base address' is not necessarily a part of it. Try this:

Typed pointers can point to objects iff the object is properly
aligned for that pointer type.
I've been writing code for years on various 8, 16 & 32 bit
platforms but never noticed this subtlety. Anything else
I'm missing?

Have you ever programmed on a SPARC (Sun) CPU ? They have
alignment and the program blows up if you violate it. Try this:

int main(void)
{
char *pc = malloc(10);
int *pi = (int *)(pc + 1);
*pi = 0;
}

It's possible for compilers to 'work around' this by noticing if
you do an unaligned access, and converting your code into a bunch
of instructions to work with chars. But gcc, for one, doesn't do
this by default.

Many embedded platforms also have "forced" alignment like this.
Other platforms such as IA32 allow unaligned accesses, but they
just run slower (the CPU will break it up into multiple single-
char accesses, behind the scenes).
 
R

Richard Bos

But I don't understand how malloc can be made to work with these rules.
Doesn't malloc just return a void pointer which in normal use you
assign to a variable you want. Isn't the following *normal* code?

struct mystruct *myptr;
myptr = malloc(sizeof(myptr));

Yes. You're right, that's another exception, but it's also explicitly
mentioned in the Standard's definition of the memory management
functions:
# The pointer returned if the allocation succeeds is suitably aligned so
# that it may be assigned to a pointer to any type of object and then
# used to access such an object or an array of such objects in the space
# allocated (until the space is explicitly deallocated).
Or is what Simon Biber said true, that is, the C runtime does some
pointer conversion in the background in this case.

If void pointers do not have the same representation as, say, int
pointers, then the C runtime code (or the compiled program, or the
interpreter, or whatever) must do pointer conversion _every_ time a void
pointer is assigned to an int pointer, and vice versa. However, in the
cases mentioned above, the conversion _must_ succeed; in any other case,
it needn't. Unless I've forgotten an exception again :-/

Richard
 
P

pete

pete said:
(e-mail address removed) wrote:

I read your discussion with Kieth.
There's no way to get a "void object" that isn't
properly aligned, so the "only if" part isn't necessary.

I take that back. It's only the first byte of the malloc
reserved object that is properly aligned for every type.
If you want to assign the address of a subsequent byte
to an object type pointer,
then you do have to be careful, as you stated.
 
M

Michael Wojcik

For suitably restricted definitions of "standard practice", perhaps.
I think it's workable because Unix compilers supports this more than
anything else.

There are implementations for POSIX-compliant systems (some of which
are also Unix-branded, or were back when that was an option; I'm not
sure what the current status of the "Unix" trademark is) where this
is not permissible in the general case.

The most common issue is alignment. There are many POSIX systems
with strict alignment requirements, so pointing a pointer-to-struct
to an arbitrary offset in a buffer and then dereferencing it is
likely to produce not very useful results (SIGBUS, on typical POSIX
systems, though some - eg POSIX-compliant versions of OS/400 running
ILE-mode programs - have other ways of showing their displeasure).
I have seen TCP/IP code which does not do this though (extract data via
struct pointers).

The vast majority of the comms code I've read, and certainly all I've
written (thousands of SLOC) for at least the past decade or so, don't
do this. There's no substitute for proper data marshalling. Done
right, it's completely portable (or, in some cases, portable to all
systems with the appropriate sizes and limits - complete portability
isn't always worth the cost); there's no need to know the alignment
requirements or byte ordering of the implementation. It Just Works.

While it might be nice if C had syntactic sugar for marshalling data,
it doesn't, and pretending that it does by pointing to structs where
no struct exists is a recipie for future maintenance woes. My advice
is to not allow your code to be contaminated by others' bad practices.

--
Michael Wojcik (e-mail address removed)

Duck: No secret what's worth a hoot ought to be kept quiet.
Pogo: Secrets is usually perty doggone fascinatin'.
Duck: Egg-zackly ... it's completely illogical to keep a secret secret.
Pogo: An' unfair. -- Walt Kelly
 
M

Michael Wojcik

To sum up:

1. Not all pointers are created equal.
2. Void and char pointers are compatible due to historical reasons.
3. Void pointers can point to anything.
4. Typed pointers can point to void objects only if the object is
properly aligned to not need the extra information contained in the
void pointer. That is, it only needs the 'base address'.

I've been writing code for years on various 8, 16 & 32 bit platforms
but never noticed this subtlety. Anything else I'm missing?

Others have already commented on the list. I'll add one item I
think is missing:

5. A pointer need not contain anything that directly corresponds to
a "machine address".

In the C implementations for the AS/400, for example, all pointers
are 128-bit objects which contain type, space, and offset informa-
tion. CPU addresses for the '400, on the other hand, are 32- or
64-bit linear quantities.


--
Michael Wojcik (e-mail address removed)

It's like being shot at in an airport with all those guys running
around throwing hand grenades. Certain people function better with
hand grenades coming from all sides than other people do when the
hand grenades are only coming from inside out.
-- Dick Selcer, coach of the Cinci Bengals
 
M

Mark McIntyre

There's no way to know, since
a) C++ is offtopic here and
b) an implemetnation can emit whatever diagnostics it wants to, when
it encounters a bug.

Yes but it would be nonsense to claim "from integer" when it's in fact
an illegal conversion from [c++] void * or [pre-ansi] char *

Yea, but so what? Thats a QOI issue, the compiler could emit a warning
stating that your nipples explode with delight if it so desired.

Nethack anyone ?
 
D

Default User

Mark McIntyre wrote:

Yea, but so what? Thats a QOI issue, the compiler could emit a warning
stating that your nipples explode with delight if it so desired.

Yeah, but you don't answer similar questions about C diagnostics that
way. Look, you were not informative about a different language, no
biggie. All you had to say was, "Oh, ok, whatever."



Brian
 
M

Mark McIntyre

Mark McIntyre wrote:



Yeah, but you don't answer similar questions about C diagnostics that
way. Look, you were not informative about a different language, no
biggie. All you had to say was, "Oh, ok, whatever."

Whatever
 

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
474,171
Messages
2,570,935
Members
47,472
Latest member
KarissaBor

Latest Threads

Top