Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #76755 > unrolled thread

Strict aliasing and restrict

Started byJohannes Bauer <dfnsonfsduifb@gmx.de>
First post2015-11-21 13:12 +0100
Last post2015-11-21 16:39 -0600
Articles 20 on this page of 24 — 10 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#76755 — Strict aliasing and restrict

FromJohannes Bauer <dfnsonfsduifb@gmx.de>
Date2015-11-21 13:12 +0100
SubjectStrict 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]


#76758

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-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]


#76784

Fromsupercat@casperkitty.com
Date2015-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]


#76759

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-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]


#76762

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2015-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]


#76782

Fromsupercat@casperkitty.com
Date2015-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]


#76793

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2015-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]


#76795

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2015-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]


#76850

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2015-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]


#76823

Fromsupercat@casperkitty.com
Date2015-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]


#76852

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2015-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]


#76877

Fromsupercat@casperkitty.com
Date2015-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]


#76854

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-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]


#76882

Fromsupercat@casperkitty.com
Date2015-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]


#76935

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-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]


#76940

FromIan Collins <ian-news@hotmail.com>
Date2015-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]


#76944

Fromsupercat@casperkitty.com
Date2015-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]


#76953

FromStephen Sprunk <stephen@sprunk.org>
Date2015-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]


#76990

Fromraltbos@xs4all.nl (Richard Bos)
Date2015-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]


#76767

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2015-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