Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #76755 > unrolled thread
| Started by | Johannes Bauer <dfnsonfsduifb@gmx.de> |
|---|---|
| First post | 2015-11-21 13:12 +0100 |
| Last post | 2015-11-21 16:39 -0600 |
| Articles | 20 on this page of 24 — 10 participants |
Back to article view | Back to comp.lang.c
Strict aliasing and restrict Johannes Bauer <dfnsonfsduifb@gmx.de> - 2015-11-21 13:12 +0100
Re: Strict aliasing and restrict James Kuyper <jameskuyper@verizon.net> - 2015-11-21 07:39 -0500
Re: Strict aliasing and restrict supercat@casperkitty.com - 2015-11-21 09:59 -0800
Re: Strict aliasing and restrict Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-21 12:41 +0000
Re: Strict aliasing and restrict Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-21 12:52 +0000
Re: Strict aliasing and restrict supercat@casperkitty.com - 2015-11-21 09:14 -0800
Re: Strict aliasing and restrict Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-21 19:41 +0000
Re: Strict aliasing and restrict Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-21 14:57 -0500
Re: Strict aliasing and restrict Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-22 11:02 +0000
Re: Strict aliasing and restrict supercat@casperkitty.com - 2015-11-21 17:50 -0800
Re: Strict aliasing and restrict Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-22 11:18 +0000
Re: Strict aliasing and restrict supercat@casperkitty.com - 2015-11-22 07:45 -0800
Re: Strict aliasing and restrict Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-22 03:41 -0800
Re: Strict aliasing and restrict supercat@casperkitty.com - 2015-11-22 08:02 -0800
Re: Strict aliasing and restrict Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-22 14:39 -0800
Re: Strict aliasing and restrict Ian Collins <ian-news@hotmail.com> - 2015-11-23 11:59 +1300
Re: Strict aliasing and restrict supercat@casperkitty.com - 2015-11-22 15:22 -0800
Re: Strict aliasing and restrict Stephen Sprunk <stephen@sprunk.org> - 2015-11-22 19:22 -0600
Re: Strict aliasing and restrict raltbos@xs4all.nl (Richard Bos) - 2015-11-23 14:07 +0000
Re: Strict aliasing and restrict Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-21 08:17 -0500
Re: Strict aliasing and restrict supercat@casperkitty.com - 2015-11-21 09:45 -0800
Re: Strict aliasing and restrict Stephen Sprunk <stephen@sprunk.org> - 2015-11-22 16:30 -0600
Re: Strict aliasing and restrict supercat@casperkitty.com - 2015-11-22 15:18 -0800
Re: Strict aliasing and restrict Stephen Sprunk <stephen@sprunk.org> - 2015-11-21 16:39 -0600
Page 1 of 2 [1] 2 Next page →
| From | Johannes Bauer <dfnsonfsduifb@gmx.de> |
|---|---|
| Date | 2015-11-21 13:12 +0100 |
| Subject | Strict aliasing and restrict |
| Message-ID | <n2pn3q$qv0$1@news.albasani.net> |
Hi group, I've got a question about strict aliasing and the restrict keyword. Why is "restrict" needed in the first place? It is my understanding that strict aliasing is something that any conforming compiler might assume at any point in time anyways. That would, however, contradict "restrict" -- because if strict aliasing was allowed everywhere, there would not be a need to explicitly declare it for some cases. So it appears to me that the strict aliasing rule does not apply everywhere and "restrict" gives the programmer the ability to specify explicitly that it should, however, apply here and there. If someone could clear this up for me I'd be most grateful. Thanks, Johannes -- >> Wo hattest Du das Beben nochmal GENAU vorhergesagt? > Zumindest nicht öffentlich! Ah, der neueste und bis heute genialste Streich unsere großen Kosmologen: Die Geheim-Vorhersage. - Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$1@speranza.aioe.org>
[toc] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-11-21 07:39 -0500 |
| Message-ID | <n2poi0$n1n$1@dont-email.me> |
| In reply to | #76755 |
On 11/21/2015 07:12 AM, Johannes Bauer wrote:
> Hi group,
>
> I've got a question about strict aliasing and the restrict keyword.
>
> Why is "restrict" needed in the first place? It is my understanding that
> strict aliasing is something that any conforming compiler might assume
> at any point in time anyways. That would, however, contradict "restrict"
> -- because if strict aliasing was allowed everywhere, there would not be
> a need to explicitly declare it for some cases.
7.24.2.1p1:
void *memcpy(void * restrict s1,
const void * restrict s2,
size_t n);
The restrict qualifiers make it undefined behavior to call memcpy() with
arguments that would result in the output from memcpy() overlapping the
input. As a result, the implementation of memcpy() is simplified by
reason of not having to worry about that possibility. Do you believe
that strict aliasing is redundant with this use of 'restrict'? If so,
could you explain why?
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-21 09:59 -0800 |
| Message-ID | <cd700ead-7240-47f0-934a-9b6541eb4adf@googlegroups.com> |
| In reply to | #76758 |
On Saturday, November 21, 2015 at 6:39:52 AM UTC-6, James Kuyper wrote:
> The restrict qualifiers make it undefined behavior to call memcpy() with
> arguments that would result in the output from memcpy() overlapping the
> input. As a result, the implementation of memcpy() is simplified by
> reason of not having to worry about that possibility. Do you believe
> that strict aliasing is redundant with this use of 'restrict'? If so,
> could you explain why?
It is the definition of memcpy() rather than restrict that makes such usage
illegal. It would be possible to write a version of memmove() which had
restrict qualifiers on its parameters but still behaved exactly like memmove
doing something like:
static int pointer_inside(char *needle, char *haystack, size_t size)
{
while(size--) if (haystack++ == needle) return 1;
return 0;
}
void *memmove(void *dest, void *src, int size)
{
if (pointer_inside(dest, src, size))
{
char *d=dest, *s=d+((char*)src-(char*)dest);
while(size--)
*d++ = *s++; // Note both pointers derived from dest
}
else if (pointer_inside(src, dest, size))
{
char *d=dest+size, *s=d+((char*)src-(char*)dest);
while(size--)
*--d = *--s; // Note both pointers derived from dest
}
else
memcpy(dest, src, size);
return dest;
}
The restrict qualifier doesn't mean src and dest can't alias; what it means
is that the function may only access an object using both pointers if the
object is not modified at all by any means during the execution of the
function. The above code doesn't access *any* object using *src unless the
two pointers don't overlap, so it complies with the restriction.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-21 12:41 +0000 |
| Message-ID | <87poz3o789.fsf@bsb.me.uk> |
| In reply to | #76755 |
Johannes Bauer <dfnsonfsduifb@gmx.de> writes: > Hi group, > > I've got a question about strict aliasing and the restrict keyword. > > Why is "restrict" needed in the first place? It is my understanding that > strict aliasing is something that any conforming compiler might assume > at any point in time anyways. That would, however, contradict "restrict" > -- because if strict aliasing was allowed everywhere, there would not be > a need to explicitly declare it for some cases. Strict aliasing is an invented term that does not appear in the standard. I sense that it is often used like "politically correct" -- it's never intended to be a good thing, just a label for aliasing that the author objects to. (I'm not saying you are doing that, just pointing out that it's a term best avoided). > So it appears to me that the strict aliasing rule does not apply > everywhere and "restrict" gives the programmer the ability to specify > explicitly that it should, however, apply here and there. void f(int *p1, int *p2); The effective type rules allow a compiler to assume that lvalue expressions with different types refer to distinct objects, but that's not possible in the case above. To tell the compiler that p1 and p2 don't alias you need restrict. I think, also, that the rules about restrict-qualified pointers are stronger than the effective type rules, but I'd need to research that to be sure. Also, restrict allows you to declare non-aliasing in other cases that are allowed by the effective type rules. An lvalue expression of type char, for example, can access any object, so without restrict char pointers could alias almost anything. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2015-11-21 12:52 +0000 |
| Message-ID | <slrnn50q9b.5q5.grahn+nntp@frailea.sa.invalid> |
| In reply to | #76759 |
On Sat, 2015-11-21, Ben Bacarisse wrote: > Johannes Bauer <dfnsonfsduifb@gmx.de> writes: > >> Hi group, >> >> I've got a question about strict aliasing and the restrict keyword. >> >> Why is "restrict" needed in the first place? It is my understanding that >> strict aliasing is something that any conforming compiler might assume >> at any point in time anyways. That would, however, contradict "restrict" >> -- because if strict aliasing was allowed everywhere, there would not be >> a need to explicitly declare it for some cases. > > Strict aliasing is an invented term that does not appear in the > standard. I sense that it is often used like "politically correct" -- > it's never intended to be a good thing, just a label for aliasing that > the author objects to. (I'm not saying you are doing that, just > pointing out that it's a term best avoided). When I use the term, it's positive/neutral. But I'm one of those who /don't/ have as a personal goal to rewrite the C standard or replace the language ... I just want my code to work according to the standard! /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-21 09:14 -0800 |
| Message-ID | <5831fcba-8de0-4e11-8ef9-8f6229d63935@googlegroups.com> |
| In reply to | #76762 |
On Saturday, November 21, 2015 at 6:53:08 AM UTC-6, Jorgen Grahn wrote: > When I use the term, it's positive/neutral. But I'm one of those who > /don't/ have as a personal goal to rewrite the C standard or replace > the language ... I just want my code to work according to the > standard! My goal would be to have a standard that acknowledges the kinds of systems- programming for which C was invented in the first place, and which led to C becoming popular in the 1980s and 1990s. A common mantra in the 1980s and 1990s was that if one wanted good performance one needed to avoid using malloc/free too much. Using malloc to acquire big chunks of memory and then subdividing it and recycling as necessary was a major key to getting good performance in many kinds of applications. And of course managing memory allocations is a major part of what systems programming was all about. Standard C makes it literally impossible to perform anything resembling efficient type-agnostic memory management and recycling without using malloc and free to scrub memory every time it is recycled. There is simply no mechanism to tell the compiler "I'm done using this block as whatever type I was using it; now I want to use it as something else". For the longest time I'd thought that the rules meant one had to jump through some extra hoops to allow type-agnostic memory recycling, but was really confused as to what the rules were. The rules are simple--the Standard simply forbids it. I don't think it's unreasonable to say that a language standard should support the purposes for which a language was designed and for which it has generally been the most popular choice. Do you?
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2015-11-21 19:41 +0000 |
| Message-ID | <slrnn51i83.5q5.grahn+nntp@frailea.sa.invalid> |
| In reply to | #76782 |
On Sat, 2015-11-21, supercat@casperkitty.com wrote: > On Saturday, November 21, 2015 at 6:53:08 AM UTC-6, Jorgen Grahn wrote: [strict aliasing] >> When I use the term, it's positive/neutral. But I'm one of those who >> /don't/ have as a personal goal to rewrite the C standard or replace >> the language ... I just want my code to work according to the >> standard! > > My goal would be to have a standard that acknowledges the kinds of systems- > programming for which C was invented in the first place, and which led to > C becoming popular in the 1980s and 1990s. > > A common mantra in the 1980s and 1990s was that if one wanted good > performance one needed to avoid using malloc/free too much. Using malloc > to acquire big chunks of memory and then subdividing it and recycling as > necessary was a major key to getting good performance in many kinds of > applications. And of course managing memory allocations is a major part of > what systems programming was all about. > > Standard C makes it literally impossible to perform anything resembling > efficient type-agnostic memory management and recycling without using malloc > and free to scrub memory every time it is recycled. There is simply no > mechanism to tell the compiler "I'm done using this block as whatever type > I was using it; now I want to use it as something else". For the longest > time I'd thought that the rules meant one had to jump through some extra > hoops to allow type-agnostic memory recycling, but was really confused as > to what the rules were. The rules are simple--the Standard simply forbids > it. > > I don't think it's unreasonable to say that a language standard should > support the purposes for which a language was designed and for which it has > generally been the most popular choice. Do you? No, but the needs you describe have never been my needs. Casts and unions (apart from the simplest cases) are things I've never or almost never had reason to use. I have fixed quite a few bugs in other peoples' code by eliminating casts -- but to be fair that has mostly been bugs of the form "I know this struct is implemented as this series of octets; padding, endianness and so on. (I'm interested in tools to help me find such bugs.) The bottom line: my code has to work with the language and the compilers I have /now/, not the ones we may have in the future. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-11-21 14:57 -0500 |
| Message-ID | <n2qi6f$sf7$1@dont-email.me> |
| In reply to | #76793 |
On 11/21/2015 2:41 PM, Jorgen Grahn wrote:
>[...]
> The bottom line: my code has to work with the language and the
> compilers I have /now/, not the ones we may have in the future.
How far off is the future?
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2015-11-22 11:02 +0000 |
| Message-ID | <slrnn5385b.5q5.grahn+nntp@frailea.sa.invalid> |
| In reply to | #76795 |
On Sat, 2015-11-21, Eric Sosman wrote: > On 11/21/2015 2:41 PM, Jorgen Grahn wrote: >>[...] >> The bottom line: my code has to work with the language and the >> compilers I have /now/, not the ones we may have in the future. > > How far off is the future? What matters to me is that it's not /now/, not the project I'm involved in. As for supercat's future, I suspect it will never come. That may be a good thing -- or not. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-21 17:50 -0800 |
| Message-ID | <bd9f6046-116b-4dc3-8d11-08283b3d6179@googlegroups.com> |
| In reply to | #76793 |
On Saturday, November 21, 2015 at 1:42:05 PM UTC-6, Jorgen Grahn wrote:
> No, but the needs you describe have never been my needs. Casts and
> unions (apart from the simplest cases) are things I've never or almost
> never had reason to use.
Something tells me that one could take a million of the machines that I've
written C code for most recently, and they'd probably have in total less RAM
than the last machine you've written C code for (does your machine have more
or less than 8 gigs)? I don't think I've written C code for a machine with
more than 128Kbytes of RAM in the last five years. I used to write C for the
PC, but now I use .NET Framework.
The sizes of processors at the low end of the microcontroller marketplace
have been growing, but it's still worlds apart from the PC. If one needs a
$0.50 CPU that can run for a year on a coin cell, one isn't going to have
megs of RAM--much less gigs--available to play with.
I suspect that much of the conflict around the evolution of C stems from
an increasing divergence between two groups of people using the language.
Some people need a systems programming language for use on hardware which
is not terribly far removed from the machines for which C was originally
designed. Others need a language that can be used for high-powered numerical
processing and other such purposes.
I think it's unfortunate that those driving the development of the language
pay no heed to embedded systems developers or people doing systems
programming on the PC since it wouldn't take much to make the language
suitable for such purposes. Totally eliminating all aliasing restrictions
would be one way, but 95% of aliasing optimizations would be somewhat useful
even in when doing systems programming. A better approach would be to add
standardized aliasing barriers, which I would think could be useful even
when doing high-end programming, especially if one added a means by which
code could explicitly disclaim the need for the character-type exception to
the normal aliasing rules.
In many cases where code would need memory barriers, they would be unlikely
to have *any* effect on the generated code, but the places where they would
cause code to be "less efficient" than without the memory barrier would be
places where the code with the barrier would work correctly and code without
the barrier wouldn't.
BTW, I've been trying to figure out what aspect of the Standard would be
violated so as to cause the following to invoke Undefined Behavior. I
can't see that anything would be, but I also would not expect compilers
to yield expected behaviors.
typedef struct struct_1 { int foo; } s1;
typedef struct struct_2 { int foo; } s2;
void test(s1 *p1, s2 *p2)
{
for (int i=0; i<100; i++)
s1[i].foo = i;
for (int i=0; i<100; i++)
s2[i].foo = i;
}
int main(void)
{
int x[101];
test((s1*)x, (s2*)(x+1));
return x[5];
}
I would expect that an aggressive compiler could try to merge both loops
into one, but the effective type of each item accessed in the loops would
be "int", and all the accesses would be via a struct which contains "int"
as a member, which is supposed to be one of the allowable cases.
I wonder why the Standard didn't simply say that compilers were allowed to
arbitrarily reorder operations on different types, and that code which
would make such reordering visible invoked Undefined Behavior? That would
seem a lot simpler than the rules as written.
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2015-11-22 11:18 +0000 |
| Message-ID | <slrnn5393f.5q5.grahn+nntp@frailea.sa.invalid> |
| In reply to | #76823 |
On Sun, 2015-11-22, supercat@casperkitty.com wrote: > On Saturday, November 21, 2015 at 1:42:05 PM UTC-6, Jorgen Grahn wrote: >> No, but the needs you describe have never been my needs. Casts and >> unions (apart from the simplest cases) are things I've never or almost >> never had reason to use. > > Something tells me that one could take a million of the machines that I've > written C code for most recently, and they'd probably have in total less RAM > than the last machine you've written C code for (does your machine have more > or less than 8 gigs)? I don't think I've written C code for a machine with > more than 128Kbytes of RAM in the last five years. I used to write C for the > PC, but now I use .NET Framework. Since 2004, I've been programming server/desktop-grade machines. The last one indeed had around 8 gigs of RAM ... that seemed absurdly much to me. A few megabytes should be plenty for a program, the way I think about it. Your systems on the other hand would feel cramped ... but I understand the use case, and would like to do more such programming in the future. ... > I suspect that much of the conflict around the evolution of C stems from > an increasing divergence between two groups of people using the language. > Some people need a systems programming language for use on hardware which > is not terribly far removed from the machines for which C was originally > designed. Others need a language that can be used for high-powered numerical > processing and other such purposes. Part of the difficulty may be that I see "the machines for which C was originally designed" as Unix time-sharing systems, not small embedded systems. But I don't know just how cramped early Unix systems were. Anyway, I can understand your viewpoint better when you say you come from tiny embedded systems. Even if I don't fully understand why you need all that aliasing or overlaying. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-22 07:45 -0800 |
| Message-ID | <baf31f48-dce1-4adb-9598-e65fd04386e6@googlegroups.com> |
| In reply to | #76852 |
On Sunday, November 22, 2015 at 5:18:17 AM UTC-6, Jorgen Grahn wrote: > Anyway, I can understand your viewpoint better when you say you come > from tiny embedded systems. Even if I don't fully understand why you > need all that aliasing or overlaying. Two big reasons: first of all, it's pretty common to have data which consist of 16-bit values, but want to be able to peform various vector-style operations on large quantities of it. On a 32-bit machine, processing data in 32-bit chunks will be almost twice as fast as doing it in 16-bit chunks, and may make the difference between the system taking 50ms to respond to a button push or 90ms, so type punning between 16-bit and 32-bit data are often very important for performance. On a broader scale, malloc() and free() are often inadequate for systems which cannot afford memory fragmentation and must be able to handle low- memory conditions gracefully. Many systems have varying needs for data of different types and thus need a means by which they can use a block of storage to hold one kind of data and later use it to hold another kind, without having to go through a malloc/free cycle.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-11-22 03:41 -0800 |
| Message-ID | <779099d5-1301-4f43-a2e9-a54f429d84d7@googlegroups.com> |
| In reply to | #76782 |
On Saturday, November 21, 2015 at 5:14:18 PM UTC, supe...@casperkitty.com wrote: > On Saturday, November 21, 2015 at 6:53:08 AM UTC-6, Jorgen Grahn wrote: > > When I use the term, it's positive/neutral. But I'm one of those who > > /don't/ have as a personal goal to rewrite the C standard or replace > > the language ... I just want my code to work according to the > > standard! > > My goal would be to have a standard that acknowledges the kinds of systems- > programming for which C was invented in the first place, and which led to > C becoming popular in the 1980s and 1990s. > > A common mantra in the 1980s and 1990s was that if one wanted good > performance one needed to avoid using malloc/free too much. Using malloc > to acquire big chunks of memory and then subdividing it and recycling as > necessary was a major key to getting good performance in many kinds of > applications. And of course managing memory allocations is a major part of > what systems programming was all about. > > Standard C makes it literally impossible to perform anything resembling > efficient type-agnostic memory management and recycling without using malloc > and free to scrub memory every time it is recycled. There is simply no > mechanism to tell the compiler "I'm done using this block as whatever type > I was using it; now I want to use it as something else". For the longest > time I'd thought that the rules meant one had to jump through some extra > hoops to allow type-agnostic memory recycling, but was really confused as > to what the rules were. The rules are simple--the Standard simply forbids > it. > > I don't think it's unreasonable to say that a language standard should > support the purposes for which a language was designed and for which it has > generally been the most popular choice. Do you? > There's a glitch in the standard that makes it impossible to write a conforming malloc() in standard C. That's that malloc has to return a pointer aligned for any use, and there's no way to specify such an alignment. However in reality aligning to double will almost always work, and the only place you need the facility is in a memory allocation function itself. It's easy enough to produce a stack-based heap allocator (if you get my drift), and a fixed block allocator. You can them simply cast the void pointer returned by the custom allocator to the type you desire, should you, for example, want a fixed block allocator that you're using for several small but different-sized block. It needs to return the biggest block, so you lose a bit of memory, but you can reuse the block at will, without even calling the allocator again if three machine instructions of overhead is too much for you.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-22 08:02 -0800 |
| Message-ID | <f0b3423a-1782-4321-906a-b325bc7a891f@googlegroups.com> |
| In reply to | #76854 |
On Sunday, November 22, 2015 at 5:41:19 AM UTC-6, Malcolm McLean wrote:
> On Saturday, November 21, 2015 at 5:14:18 PM UTC, supercat wrote:
> > Standard C makes it literally impossible to perform anything resembling
> > efficient type-agnostic memory management and recycling without using malloc
> > and free to scrub memory every time it is recycled.
> There's a glitch in the standard that makes it impossible to write a conforming
> malloc() in standard C. That's that malloc has to return a pointer aligned for
> any use, and there's no way to specify such an alignment.
That could easily be overcome. There's a *MUCH* bigger problem, which for
some reason a lot of programmers are blind to.
> It needs to return the biggest block, so you lose a bit of memory, but
> you can reuse the block at will, without even calling the allocator again if
> three machine instructions of overhead is too much for you.
You don't see the real problem. The real problem is that given:
float *fp = _box_alloc(pool); // Allocation function in rtx
*fp = 12.34;
_box_free(pool, fp);
float *ip = _box_alloc(pool); // Allocation function in rtx
*ip = 5;
printf("%d", *ip);
_box_free(pool, ip);
there's no decent way to prevent a compiler from rewriting the code as:
float *fp = _box_alloc(pool); // Allocation function in rtx
_box_free(pool, fp);
float *ip = _box_alloc(pool); // Allocation function in rtx
*ip = 5;
*fp = 12.34;
printf("%d", *ip);
_box_free(pool, ip);
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-11-22 14:39 -0800 |
| Message-ID | <837c2ee0-9f4c-4f11-8a16-e9aeac06c711@googlegroups.com> |
| In reply to | #76882 |
On Sunday, November 22, 2015 at 4:02:33 PM UTC, supe...@casperkitty.com wrote:
> On Sunday, November 22, 2015 at 5:41:19 AM UTC-6, Malcolm McLean wrote:
> > On Saturday, November 21, 2015 at 5:14:18 PM UTC, supercat wrote:
> > > Standard C makes it literally impossible to perform anything resembling
> > > efficient type-agnostic memory management and recycling without using malloc
> > > and free to scrub memory every time it is recycled.
>
> > There's a glitch in the standard that makes it impossible to write a conforming
> > malloc() in standard C. That's that malloc has to return a pointer aligned for
> > any use, and there's no way to specify such an alignment.
>
> That could easily be overcome. There's a *MUCH* bigger problem, which for
> some reason a lot of programmers are blind to.
>
> > It needs to return the biggest block, so you lose a bit of memory, but
> > you can reuse the block at will, without even calling the allocator again if
> > three machine instructions of overhead is too much for you.
>
> You don't see the real problem. The real problem is that given:
>
> float *fp = _box_alloc(pool); // Allocation function in rtx
> *fp = 12.34;
> _box_free(pool, fp);
> float *ip = _box_alloc(pool); // Allocation function in rtx
> *ip = 5;
> printf("%d", *ip);
> _box_free(pool, ip);
>
> there's no decent way to prevent a compiler from rewriting the code as:
>
> float *fp = _box_alloc(pool); // Allocation function in rtx
> _box_free(pool, fp);
> float *ip = _box_alloc(pool); // Allocation function in rtx
> *ip = 5;
> *fp = 12.34;
> printf("%d", *ip);
> _box_free(pool, ip);
>
Oh, I get it.
Yes, that's a nasty consequence of the no alias rule combined with an
aggressive optimiser. You somehow need to declare _box_alloc and
_box_free as opaque functions immune from cross function call
optimisation.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2015-11-23 11:59 +1300 |
| Message-ID | <dbevm7FjpqnU14@mid.individual.net> |
| In reply to | #76882 |
supercat@casperkitty.com wrote:
> On Sunday, November 22, 2015 at 5:41:19 AM UTC-6, Malcolm McLean wrote:
>> On Saturday, November 21, 2015 at 5:14:18 PM UTC, supercat wrote:
>>> Standard C makes it literally impossible to perform anything resembling
>>> efficient type-agnostic memory management and recycling without using malloc
>>> and free to scrub memory every time it is recycled.
>
>> There's a glitch in the standard that makes it impossible to write a conforming
>> malloc() in standard C. That's that malloc has to return a pointer aligned for
>> any use, and there's no way to specify such an alignment.
>
> That could easily be overcome. There's a *MUCH* bigger problem, which for
> some reason a lot of programmers are blind to.
>
>> It needs to return the biggest block, so you lose a bit of memory, but
>> you can reuse the block at will, without even calling the allocator again if
>> three machine instructions of overhead is too much for you.
>
> You don't see the real problem. The real problem is that given:
>
> float *fp = _box_alloc(pool); // Allocation function in rtx
> *fp = 12.34;
> _box_free(pool, fp);
> float *ip = _box_alloc(pool); // Allocation function in rtx
> *ip = 5;
> printf("%d", *ip);
> _box_free(pool, ip);
>
> there's no decent way to prevent a compiler from rewriting the code as:
>
> float *fp = _box_alloc(pool); // Allocation function in rtx
> _box_free(pool, fp);
> float *ip = _box_alloc(pool); // Allocation function in rtx
> *ip = 5;
> *fp = 12.34;
> printf("%d", *ip);
> _box_free(pool, ip);
This would change the observable behaviour of the code. A more likely
rearrangement would be:
float *fp = _box_alloc(pool); // Allocation function in rtx
_box_free(pool, fp);
float *ip = _box_alloc(pool); // Allocation function in rtx
*fp = 12.34;
*ip = 5;
printf("%d", *ip);
_box_free(pool, ip);
which does not change the observable behaviour of the code.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-22 15:22 -0800 |
| Message-ID | <d8e0a0a8-be19-43ea-925a-bae0eb519ec9@googlegroups.com> |
| In reply to | #76940 |
On Sunday, November 22, 2015 at 4:59:27 PM UTC-6, Ian Collins wrote:
> supercat wrote:
> > there's no decent way to prevent a compiler from rewriting the code as:
> >
> > float *fp = _box_alloc(pool); // Allocation function in rtx
> > _box_free(pool, fp);
> > float *ip = _box_alloc(pool); // Allocation function in rtx
> > *ip = 5;
> > *fp = 12.34;
> > printf("%d", *ip);
> > _box_free(pool, ip);
>
> This would change the observable behaviour of the code.
How would it change the observable behavior of any *defined* execution of
the code? If the second _box_alloc returns a block of memory which
either has an effective type of "float" or has never had an effective type
then the above rewrite would not affect the behavior of the code, and if
the second _box_alloc does not do one of those things the Standard won't
impose any requirements on what the compiler might do.
[toc] | [prev] | [next] | [standalone]
| From | Stephen Sprunk <stephen@sprunk.org> |
|---|---|
| Date | 2015-11-22 19:22 -0600 |
| Message-ID | <n2tpjp$rua$1@dont-email.me> |
| In reply to | #76882 |
On 22-Nov-15 10:02, supercat@casperkitty.com wrote:
> Malcolm McLean wrote:
>> It needs to return the biggest block, so you lose a bit of memory,
>> but you can reuse the block at will, without even calling the
>> allocator again if three machine instructions of overhead is too
>> much for you.
>
> You don't see the real problem. The real problem is that given:
>
> float *fp = _box_alloc(pool); // Allocation function in rtx
> *fp = 12.34;
> _box_free(pool, fp);
> float *ip = _box_alloc(pool); // Allocation function in rtx
> *ip = 5;
> printf("%d", *ip);
> _box_free(pool, ip);
>
> there's no decent way to prevent a compiler from rewriting the code as:
>
> float *fp = _box_alloc(pool); // Allocation function in rtx
> _box_free(pool, fp);
> float *ip = _box_alloc(pool); // Allocation function in rtx
> *ip = 5;
> *fp = 12.34;
> printf("%d", *ip);
> _box_free(pool, ip);
That reordering is not allowed unless the compiler can prove neither ip
nor fp (nor pool?) point to allocated storage. If they do, the behavior
is well-defined. If they don't, the behavior may already be undefined
for other reasons, in which case this is the least of your problems.
S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
[toc] | [prev] | [next] | [standalone]
| From | raltbos@xs4all.nl (Richard Bos) |
|---|---|
| Date | 2015-11-23 14:07 +0000 |
| Message-ID | <56531d69.12094687@news.xs4all.nl> |
| In reply to | #76854 |
Malcolm McLean <malcolm.mclean5@btinternet.com> wrote: > There's a glitch in the standard that makes it impossible to write a conforming > malloc() in standard C. That's not a glitch, that's one of the reasons why malloc() is in the library in the first place. Richard
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-11-21 08:17 -0500 |
| Message-ID | <n2pqoo$soc$1@dont-email.me> |
| In reply to | #76755 |
On 11/21/2015 7:12 AM, Johannes Bauer wrote:
> Hi group,
>
> I've got a question about strict aliasing and the restrict keyword.
>
> Why is "restrict" needed in the first place? It is my understanding that
> strict aliasing is something that any conforming compiler might assume
> at any point in time anyways. That would, however, contradict "restrict"
> -- because if strict aliasing was allowed everywhere, there would not be
> a need to explicitly declare it for some cases.
Roughly speaking, the aliasing rules say that if you have a T* and
a U* (for different types T and U), they can be assumed not to point at
the same storage.
But what if you have two T* parameters?
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web