Re: large files: when ubiquitous?
From: P.T. Breuer (ptb_at_oboe.it.uc3m.es)
Date: 05/08/04
- Next message: Andrea Treccani: "ppc edge triggered interrupt"
- Previous message: Kasper Dupont: "Re: large files: when ubiquitous?"
- In reply to: Kasper Dupont: "Re: large files: when ubiquitous?"
- Next in thread: Kasper Dupont: "Re: large files: when ubiquitous?"
- Reply: Kasper Dupont: "Re: large files: when ubiquitous?"
- Reply: Don Waugaman: "Re: large files: when ubiquitous?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sat, 08 May 2004 15:20:12 GMT
Kasper Dupont <kasperd@daimi.au.dk> wrote:
> "P.T. Breuer" wrote:
> >
> > It says reading anything from a char* is always OK (as far as I can
> > make out), but I would disagree - surely a char* can have any
> > alignment? Not necessarily one that matches the alignment of the
> > type you want to read.
>
> The discussion is not about alignment at all. It is about
> optimizations performed by the compiler. If you have a
> pointer to a float, and another pointer to a long, the
> compiler may assume chaning the one would not change the
> other.
The compiler can safely make no optimization assumptions at all on an
indirection in C. Just to be silly, the pointer might be into shared
memory - you're not then even the only thread with access.
It's only safe when you can prove that no other functional unit has
write access there, which is nearly freaking impossible in C.
> Eg. this program print 1078523331 when compiled without
> optimization, and print 42 when compiled with -O3
>
> #include <stdio.h>
> #include <stdlib.h>
> long f(long *a, float *b)
> {
> *a=42;
> *b=3.14;
> return *a;
> }
Oh great. When both addresses are the same one or the other write wins.
Well, as you can see, it's not safe to elide the *b = 3.14 here.
Compiler mistake if it does. Send in bug report. Rewrite code for f as
inline local function using parents variables, or macro.
> int main()
> {
> void *p=malloc(42);
> printf("%ld\n",f(p,p));
Hmm. You don't seem to object to void* there! As I said below, at least
void* is a contractural promise that it's 4-aligned. Making promises is
a good thing, in general, imo.
If we pass char* instead to f, then we would be implictly saying that we
don't guarantee to f that its parameters in this instance are even
aligned the way f's prototype says they should be, which in my opinion
ought to generate a compiler warning.
Yet the info page seems to say that passing char* turns off "type
punning" checks.
The practice of reading from a different union member than the one
most recently written to (called "type-punning") is common. Even
with `-fstrict-aliasing', type-punning is allowed, provided the
memory is accessed through the union type.
...
For example, an `unsigned int' can alias an `int', but not a `void*'
or a `double'. A character type may alias any other type.
(I'm not absolutely sure what they meant in the last, but I think they
mean to refer to char*, where "character type" refers to the content of
the indirection).
So do you think the compiler will warn you about type punning in your
example?
> return 0;
> }
>
> > Wouldn't reading "anything" from a void* be safer?
>
> Dereferencing a void shouldn't be allowed at all.
Nobody does - they cast the address to (other*) first. I meant
int *x = (void*)silly_address;
There is no read of a void.
> The reason a char pointer is not assumed to point at
> different address than any other pointer is, that you
> can do stuff like reading, writing, copying data of
> any type by using a char pointer.
>
> > It's certainly common in the kernel to pass foo(void *data)
> > and then at the receiving end read mystruct *x = data;
>
> But by the time you derefernce the pointer it is no
> longer a void pointer,
Nor is there when you read "anything" from a void*.
> so the discussion about type
> punning doesn't apply at all.
Then what ARE we talking about? I'll try and look up some debian type
punning warning reports of mine ..
In function `masterpropagate':
2732: warning: dereferencing type-punned pointer will break strict-aliasing rules
2734: warning: dereferencing type-punned pointer will break strict-aliasing rules
int i;
int pid;
struct d_db * spids_db = &self->spids;
for (
***** i = spids_db->first(spids_db, (void**)&pid,NULL);
i >= 0;
***** i = spids_db->next (spids_db,i,(void**)&pid,NULL)
) {
and the methods are of type
int (*first)(struct d_db * self, void **nam, void **val);
int (*next) (struct d_db * self, int i, void **nam, void **val);
The calls match the prototypes. What is it complaining about?
> Actually that variable
> might as well have been passed as a char pointer. It
Ah.
> would be ugly, but it would work exactly the same.
Well, char* seems to be the only way to avoid complaints, according to
info. Whether you want to avoid it is another matter.
Peter
- Next message: Andrea Treccani: "ppc edge triggered interrupt"
- Previous message: Kasper Dupont: "Re: large files: when ubiquitous?"
- In reply to: Kasper Dupont: "Re: large files: when ubiquitous?"
- Next in thread: Kasper Dupont: "Re: large files: when ubiquitous?"
- Reply: Kasper Dupont: "Re: large files: when ubiquitous?"
- Reply: Don Waugaman: "Re: large files: when ubiquitous?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|