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


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

alloca()-support

Started byBonita Montero <Bonita.Montero@gmail.com>
First post2019-09-30 14:02 +0200
Last post2019-10-05 14:08 -0700
Articles 20 on this page of 109 — 21 participants

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


Contents

  alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 14:02 +0200
    Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 16:09 +0200
      Re: alloca()-support Bo Persson <bo@bo-persson.se> - 2019-09-30 17:29 +0200
        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 17:33 +0200
    Re: alloca()-support Anton Shepelev <anton.txt@g{oogle}mail.com> - 2019-09-30 17:12 +0300
      Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 16:16 +0200
        Re: alloca()-support Anton Shepelev <anton.txt@g{oogle}mail.com> - 2019-09-30 17:30 +0300
          Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 16:44 +0200
            Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-02 00:36 +0300
              Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:28 +0200
                Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-02 16:08 +0300
                  Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 15:42 +0200
      Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 14:30 +0000
        Re: alloca()-support Anton Shepelev <anton.txt@g{oogle}mail.com> - 2019-09-30 17:33 +0300
          Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-09-30 16:56 +0200
      Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-09-30 15:29 +0000
        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 17:31 +0200
          Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-01 07:03 +0000
            Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 10:57 +0200
              Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-01 18:49 +0000
                Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 21:20 +0200
                  Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-01 20:39 +0000
                  Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:15 +0000
                    Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:28 +0200
                      Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:29 +0000
      Re: alloca()-support Keith Thompson <kst-u@mib.org> - 2019-09-30 11:14 -0700
    Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 18:04 +0200
      Re: alloca()-support William Ahern <william@25thandClement.com> - 2019-09-30 11:01 -0700
        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:19 +0200
      Re: alloca()-support Paavo Helde <myfirstname@osa.pri.ee> - 2019-09-30 22:26 +0300
        Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 19:46 +0000
      Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:32 +0200
        Re: alloca()-support Paavo Helde <myfirstname@osa.pri.ee> - 2019-10-01 09:08 +0300
          Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 08:35 +0200
    Re: alloca()-support gazelle@shell.xmission.com (Kenny McCormack) - 2019-09-30 16:26 +0000
    Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 18:48 +0200
      Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 18:51 +0200
        Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 18:55 +0200
          Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 18:58 +0200
            Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 19:53 +0200
              Re: alloca()-support Keith Thompson <kst-u@mib.org> - 2019-09-30 11:13 -0700
                Re: alloca()-support Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-10-06 06:16 -0700
                  Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-06 16:22 +0300
                    Re: alloca()-support Keith Thompson <kst-u@mib.org> - 2019-10-06 12:58 -0700
                      Re: alloca()-support "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2019-10-06 13:16 -0700
              Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 19:38 +0000
                Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:41 +0200
                  Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-01 15:19 +0000
                    Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 17:31 +0200
                      Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-01 18:58 +0000
                        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 21:24 +0200
                          Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:28 +0000
                            Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:30 +0200
                              Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:36 +0000
                                Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:01 +0200
                              Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:42 +0000
                                Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:10 +0200
                                  Re: alloca()-support Mel <mel@zzzzz.com> - 2019-10-02 15:13 +0200
                      Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-01 21:10 +0200
                        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 21:25 +0200
                          Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-01 20:44 +0000
                          Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-01 23:26 +0200
                            Re: alloca()-support Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-10-01 21:08 -0600
                              Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:19 +0200
                            Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:39 +0200
                              Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:34 +0200
                          Re: alloca()-support Mel <mel@zzzzz.com> - 2019-10-02 15:14 +0200
                      Re: alloca()-support Mel <mel@zzzzz.com> - 2019-10-02 15:18 +0200
                        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 15:21 +0200
                          Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-03 04:09 +0000
                            Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-03 07:48 +0200
                              Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-03 05:49 +0000
                                Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-03 07:52 +0200
                                  Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-03 06:46 +0000
                                    Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-03 10:59 +0200
                Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-10-03 13:39 +0200
                  Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-03 13:23 +0000
                  Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-03 15:38 +0200
                    Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-03 14:51 +0000
                      Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-04 09:49 +0200
                    Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-10-03 21:47 +0200
                      Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-04 09:53 +0200
                    Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-10-03 21:52 +0200
              Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:39 +0200
          Re: alloca()-support James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-09-30 21:36 -0400
        Re: alloca()-support Philipp Klaus Krause <pkk@spth.de> - 2019-09-30 19:14 +0200
          Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 19:16 +0200
            Re: alloca()-support Robert Wessel <robertwessel2@yahoo.com> - 2019-10-01 00:18 -0500
              Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:43 +0200
              Re: alloca()-support Keith Thompson <kst-u@mib.org> - 2019-10-01 02:42 -0700
                Re: alloca()-support James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-10-01 08:11 -0400
                Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 14:53 +0200
        Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 17:52 +0000
      Re: alloca()-support Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-09-30 11:20 -0600
        Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 19:42 +0200
          Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 20:02 +0200
        Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 19:54 +0200
          Re: alloca()-support Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-09-30 14:28 -0600
            Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-01 09:38 +0200
        Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 20:01 +0200
          Re: alloca()-support Manfred <noname@add.invalid> - 2019-10-01 17:45 +0200
    Re: alloca()-support "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2019-10-02 02:35 -0700
      Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-02 16:26 +0300
        Re: alloca()-support jadill33@gmail.com - 2019-10-02 08:00 -0700
          Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-03 02:38 +0300
            Re: alloca()-support jadill33@gmail.com - 2019-10-03 08:42 -0700
        Re: alloca()-support "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2019-10-02 12:33 -0700
          Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-03 01:47 +0300
            Re: alloca()-support "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2019-10-05 14:08 -0700

Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6  Next page →


#146463

FromKeith Thompson <kst-u@mib.org>
Date2019-09-30 11:13 -0700
Message-ID<lneezx3b6b.fsf@kst-u.example.com>
In reply to#146457
Soviet_Mario <SovietMario@CCCP.MIR> writes:
> On 30/09/2019 18:58, Bonita Montero wrote:
>>>>> Since when (if at any time) was variable size automatic 
>>>>> array supported ?
>> 
>>>> Since C99.
>> 
>>> for curiosity, this feature has one or more of the 
>>> limitations I feared ... or even none of them ?
>> 
>> Yes, you could run out of stack-space, maybe hitting a 
>> guard-page
>> in the best case so that you wouldn't corrupt any other data.
>
> uhm, I didn't mean THAT kind of risk (unavoidable), but the 
> possible difficulties in defining variables beyond the point 
> of declaration of the variable-size array.
>
> I can't figure out how the compiler would reference them in 
> standard efficient ways (use of registers).
>
> Anyway, the difference with alloca () would be in a safer 
> management of possible collisions and running out of stack 
> space ? (compared with the plain declarations) ?

No.  Neither VLAs nor alloca() provide any protection against running
out of space.  Both have undefined behavior if there isn't enough memory
for the allocation.

alloca() (which, again, is non-standard) is a function that returns a
pointer.  It has no provision to return a null pointer on failure.

Defining a VLA, on the other hand, creates an array object to which you
can meaningfully apply sizeof.

Also, space allocated by alloca() is deallocated on return from the
enclosing function, not at the end of the enclosing block.

Since alloca() is a function, it can be invoked in contexts where a VLA
can't be created.  If you call alloca() as part of a function argument,
it's likely to corrupt the stack.

VLAs were introduced in C99 and made optional in C11 and are not
supported, except perhaps as an extension, in C++.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#146633

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2019-10-06 06:16 -0700
Message-ID<86k19i9fpa.fsf@linuxsc.com>
In reply to#146463
Keith Thompson <kst-u@mib.org> writes:

> Soviet_Mario <SovietMario@CCCP.MIR> writes:
>
>> On 30/09/2019 18:58, Bonita Montero wrote:
>>
>>>>>> Since when (if at any time) was variable size automatic
>>>>>> array supported ?
>>>>>
>>>>> Since C99.
>>>>
>>>> for curiosity, this feature has one or more of the
>>>> limitations I feared ... or even none of them ?
>>>
>>> Yes, you could run out of stack-space, maybe hitting a
>>> guard-page
>>> in the best case so that you wouldn't corrupt any other data.
>>
>> uhm, I didn't mean THAT kind of risk (unavoidable), but the
>> possible difficulties in defining variables beyond the point
>> of declaration of the variable-size array.
>>
>> I can't figure out how the compiler would reference them in
>> standard efficient ways (use of registers).
>>
>> Anyway, the difference with alloca () would be in a safer
>> management of possible collisions and running out of stack
>> space ? (compared with the plain declarations) ?
>
> No.  Neither VLAs nor alloca() provide any protection against
> running out of space.  Both have undefined behavior if there isn't
> enough memory for the allocation.

The function alloca() is extra-linguistic, and is not -- nor can
it be -- written in C.  From that point of view it has undefined
behavior no matter what argument value is given.

Declaring a VLA that needs more memory than is available is not
undefined behavior, any more than declaring a fixed-size array of
the same size is undefined behavior.  Both can blow up at
runtime, but neither one is undefined behavior.

[toc] | [prev] | [next] | [standalone]


#146635

FromAnton Shepelev <anton.txt@gmail.com>
Date2019-10-06 16:22 +0300
Message-ID<20191006162239.b214b09d088548cf60487316@gmail.com>
In reply to#146633
Tim Rentsch:

> The function alloca() is extra-linguistic, and is
> not -- nor can it be -- written in C.  From that point of
> view it has undefined behavior no matter what argument
> value is given.

That is my opinion exactly.  alloca() is a transcendental
beast.

-- 
()  ascii ribbon campaign -- against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#146658

FromKeith Thompson <kst-u@mib.org>
Date2019-10-06 12:58 -0700
Message-ID<ln4l0lwsr8.fsf@kst-u.example.com>
In reply to#146635
Anton Shepelev <anton.txt@gmail.com> writes:
> Tim Rentsch:
>> The function alloca() is extra-linguistic, and is
>> not -- nor can it be -- written in C.  From that point of
>> view it has undefined behavior no matter what argument
>> value is given.
>
> That is my opinion exactly.  alloca() is a transcendental
> beast.

The documentation for alloca() (at least on my Ubuntu system) says:

    The alloca() function returns a pointer to the beginning of the
    allocated space.  If the allocation causes stack overflow, program
    behavior is undefined.

I'll admit that my use of the phrase "undefined behavior" upthread was
imprecise.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#146660

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2019-10-06 13:16 -0700
Message-ID<qndi25$2o0$2@gioia.aioe.org>
In reply to#146658
On 10/6/2019 12:58 PM, Keith Thompson wrote:
> Anton Shepelev <anton.txt@gmail.com> writes:
>> Tim Rentsch:
>>> The function alloca() is extra-linguistic, and is
>>> not -- nor can it be -- written in C.  From that point of
>>> view it has undefined behavior no matter what argument
>>> value is given.
>>
>> That is my opinion exactly.  alloca() is a transcendental
>> beast.
> 
> The documentation for alloca() (at least on my Ubuntu system) says:
> 
>      The alloca() function returns a pointer to the beginning of the
>      allocated space.  If the allocation causes stack overflow, program
>      behavior is undefined.

Indeed! Scary, as if it wants to act like an uncontrolled recursion.

> 
> I'll admit that my use of the phrase "undefined behavior" upthread was
> imprecise.
> 

[toc] | [prev] | [next] | [standalone]


#146469

Fromscott@slp53.sl.home (Scott Lurndal)
Date2019-09-30 19:38 +0000
Message-ID<lRskF.22050$XA2.21391@fx05.iad>
In reply to#146457
Soviet_Mario <SovietMario@CCCP.MIR> writes:
>On 30/09/2019 18:58, Bonita Montero wrote:
>>>>> Since when (if at any time) was variable size automatic 
>>>>> array supported ?
>> 
>>>> Since C99.
>> 
>>> for curiosity, this feature has one or more of the 
>>> limitations I feared ... or even none of them ?
>> 
>> Yes, you could run out of stack-space, maybe hitting a 
>> guard-page
>> in the best case so that you wouldn't corrupt any other data.
>
>uhm, I didn't mean THAT kind of risk (unavoidable), but the 
>possible difficulties in defining variables beyond the point 
>of declaration of the variable-size array.
>
>I can't figure out how the compiler would reference them in 
>standard efficient ways (use of registers).


     mov %rsp, %rax     # rax now has starting address of alloca() region
     sub %rcx, %rsp     # rcx is the number of bytes being allocated.

....

     mov %rsp, %rbx     # rbx now has starting address of second alloca() region
     sub %rdx, %rsp     # rdx is the number of bytes being allocated
....
     ret                # all alloca storage is deallocated

(AT&T form)

It can always spill rax or rbx to the stack under register pressure.

[toc] | [prev] | [next] | [standalone]


#146486

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-10-01 07:41 +0200
Message-ID<qmuov1$n71$2@news.albasani.net>
In reply to#146469
>       mov %rsp, %rax     # rax now has starting address of alloca() region

The compiler usually uses RPB to remember the frame-pointer-address
at the prolog of the function. EBP is more suitable because it can
be restored in one step by the x86 LEAVE-instruction.

>       sub %rcx, %rsp     # rcx is the number of bytes being allocated.
> ....

[toc] | [prev] | [next] | [standalone]


#146498

Fromscott@slp53.sl.home (Scott Lurndal)
Date2019-10-01 15:19 +0000
Message-ID<J7KkF.4573$KB2.3280@fx02.iad>
In reply to#146486
Bonita Montero <Bonita.Montero@gmail.com> writes:
>>       mov %rsp, %rax     # rax now has starting address of alloca() region
>
>The compiler usually uses RPB to remember the frame-pointer-address
>at the prolog of the function. EBP is more suitable because it can
>be restored in one step by the x86 LEAVE-instruction.

So what?  The RSP is restored automatically by the ret instruction.

int f(unsigned long len)
{
    char *f = alloca(len);

    for (int i=0; i < 0; i++) {
        *f++ = '\0';
    }
    return 0;
}

gcc output:

0000000000400540 <f>:
#include <alloca.h>
#include <stdlib.h>

int f(unsigned long len)
{
  400540:       55                      push   %rbp
  400541:       48 89 e5                mov    %rsp,%rbp
  400544:       48 83 ec 20             sub    $0x20,%rsp
  400548:       48 89 7d e8             mov    %rdi,-0x18(%rbp)
    char *f = alloca(len);
  40054c:       48 8b 45 e8             mov    -0x18(%rbp),%rax
  400550:       48 8d 50 0f             lea    0xf(%rax),%rdx
  400554:       b8 10 00 00 00          mov    $0x10,%eax
  400559:       48 83 e8 01             sub    $0x1,%rax
  40055d:       48 01 d0                add    %rdx,%rax
  400560:       b9 10 00 00 00          mov    $0x10,%ecx
  400565:       ba 00 00 00 00          mov    $0x0,%edx
  40056a:       48 f7 f1                div    %rcx
  40056d:       48 6b c0 10             imul   $0x10,%rax,%rax


  400571:       48 29 c4                sub    %rax,%rsp <===== Alloca(len)
  400574:       48 89 e0                mov    %rsp,%rax <===== Remember f in %rax


  400577:       48 83 c0 0f             add    $0xf,%rax  <===== Align it
  40057b:       48 c1 e8 04             shr    $0x4,%rax
  40057f:       48 c1 e0 04             shl    $0x4,%rax
  400583:       48 89 45 f8             mov    %rax,-0x8(%rbp)  <== And save in stack frame

    for (int i=0; i < 0; i++) {
  400587:       c7 45 f4 00 00 00 00    movl   $0x0,-0xc(%rbp)
  40058e:       eb 13                   jmp    4005a3 <f+0x63>
        *f++ = '\0';
  400590:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  400594:       48 8d 50 01             lea    0x1(%rax),%rdx
  400598:       48 89 55 f8             mov    %rdx,-0x8(%rbp)
  40059c:       c6 00 00                movb   $0x0,(%rax)

  40059f:       83 45 f4 01             addl   $0x1,-0xc(%rbp)
  4005a3:       83 7d f4 00             cmpl   $0x0,-0xc(%rbp)
  4005a7:       78 e7                   js     400590 <f+0x50>
        *f++ = '\0';
    }
    return 0;
  4005a9:       b8 00 00 00 00          mov    $0x0,%eax
}
  4005ae:       c9                      leaveq 
  4005af:       c3                      retq   

>
>>       sub %rcx, %rsp     # rcx is the number of bytes being allocated.
>> ....

[toc] | [prev] | [next] | [standalone]


#146499

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-10-01 17:31 +0200
Message-ID<qmvrfu$j5$1@news.albasani.net>
In reply to#146498
>> The compiler usually uses RPB to remember the frame-pointer-address
>> at the prolog of the function. EBP is more suitable because it can
>> be restored in one step by the x86 LEAVE-instruction.

> So what?  The RSP is restored automatically by the ret instruction.

Yes, but LEAVE does three instructions in one step. Usually this
results in the same uOPs, but it is only one slot in the decoder.

[toc] | [prev] | [next] | [standalone]


#146502

FromMelzzzzz <Melzzzzz@zzzzz.com>
Date2019-10-01 18:58 +0000
Message-ID<LlNkF.594801$Nw3.562943@fx40.am4>
In reply to#146499
On 2019-10-01, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> The compiler usually uses RPB to remember the frame-pointer-address
>>> at the prolog of the function. EBP is more suitable because it can
>>> be restored in one step by the x86 LEAVE-instruction.
>
>> So what?  The RSP is restored automatically by the ret instruction.
>
> Yes, but LEAVE does three instructions in one step. Usually this
> results in the same uOPs, but it is only one slot in the decoder.
I never saw any compiler that uses `leave`. Especially since RBP doesn't
have to be used as optimization...


-- 
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi 
bili naoruzani. -- Mladen Gogala

[toc] | [prev] | [next] | [standalone]


#146505

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-10-01 21:24 +0200
Message-ID<qn095f$3qm$1@news.albasani.net>
In reply to#146502
>> Yes, but LEAVE does three instructions in one step. Usually this
>> results in the same uOPs, but it is only one slot in the decoder.

> I never saw any compiler that uses `leave`.

MSVC and gcc always use LEAVE when you have dynamic stack-frames
with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:

#include <stddef.h>

void f( size_t s )
{
	int volatile a[s];
	a[s - 1] = 123;
}


     .file    "x.c"
     .text
     .p2align 4,,15
     .globl    f
     .type    f, @function
f:
.LFB0:
     .cfi_startproc
     leaq    18(,%rdi,4), %rax
     pushq    %rbp
     .cfi_def_cfa_offset 16
     .cfi_offset 6, -16
     subq    $1, %rdi
     andq    $-16, %rax
     movq    %rsp, %rbp
     .cfi_def_cfa_register 6
     subq    %rax, %rsp
     movl    $123, (%rsp,%rdi,4)
     leave
     .cfi_def_cfa 7, 8
     ret
     .cfi_endproc
.LFE0:
     .size    f, .-f
     .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
     .section    .note.GNU-stack,"",@progbits

[toc] | [prev] | [next] | [standalone]


#146514

FromMelzzzzz <Melzzzzz@zzzzz.com>
Date2019-10-02 04:28 +0000
Message-ID<MHVkF.568895$bS1.507387@fx13.am4>
In reply to#146505
On 2019-10-01, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>
>>> Yes, but LEAVE does three instructions in one step. Usually this
>>> results in the same uOPs, but it is only one slot in the decoder.
>
>> I never saw any compiler that uses `leave`.
>
> MSVC and gcc always use LEAVE when you have dynamic stack-frames
> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>
> #include <stddef.h>
>
> void f( size_t s )
> {
> 	int volatile a[s];
> 	a[s - 1] = 123;
> }
>
>
>      .file    "x.c"
>      .text
>      .p2align 4,,15
>      .globl    f
>      .type    f, @function
> f:
> .LFB0:
>      .cfi_startproc
>      leaq    18(,%rdi,4), %rax
>      pushq    %rbp
>      .cfi_def_cfa_offset 16
>      .cfi_offset 6, -16
>      subq    $1, %rdi
>      andq    $-16, %rax
>      movq    %rsp, %rbp
>      .cfi_def_cfa_register 6
>      subq    %rax, %rsp
>      movl    $123, (%rsp,%rdi,4)
>      leave
>      .cfi_def_cfa 7, 8
>      ret
>      .cfi_endproc
> .LFE0:
>      .size    f, .-f
>      .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>      .section    .note.GNU-stack,"",@progbits
Yes, this is against optimisations as you use volatile...

-- 
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi 
bili naoruzani. -- Mladen Gogala

[toc] | [prev] | [next] | [standalone]


#146517

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-10-02 06:30 +0200
Message-ID<qn1950$hai$3@news.albasani.net>
In reply to#146514
>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>
>> #include <stddef.h>
>>
>> void f( size_t s )
>> {
>> 	int volatile a[s];
>> 	a[s - 1] = 123;
>> }
>>
>>
>>       .file    "x.c"
>>       .text
>>       .p2align 4,,15
>>       .globl    f
>>       .type    f, @function
>> f:
>> .LFB0:
>>       .cfi_startproc
>>       leaq    18(,%rdi,4), %rax
>>       pushq    %rbp
>>       .cfi_def_cfa_offset 16
>>       .cfi_offset 6, -16
>>       subq    $1, %rdi
>>       andq    $-16, %rax
>>       movq    %rsp, %rbp
>>       .cfi_def_cfa_register 6
>>       subq    %rax, %rsp
>>       movl    $123, (%rsp,%rdi,4)
>>       leave
>>       .cfi_def_cfa 7, 8
>>       ret
>>       .cfi_endproc
>> .LFE0:
>>       .size    f, .-f
>>       .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>>       .section    .note.GNU-stack,"",@progbits

> Yes, this is against optimisations as you use volatile...

I use volatile to prevent the compiler from optimizing away the
function body.

[toc] | [prev] | [next] | [standalone]


#146518

FromMelzzzzz <Melzzzzz@zzzzz.com>
Date2019-10-02 04:36 +0000
Message-ID<mPVkF.569662$R83.227680@fx23.am4>
In reply to#146517
On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>
>>> #include <stddef.h>
>>>
>>> void f( size_t s )
>>> {
>>> 	int volatile a[s];
>>> 	a[s - 1] = 123;
>>> }
>>>
>>>
>>>       .file    "x.c"
>>>       .text
>>>       .p2align 4,,15
>>>       .globl    f
>>>       .type    f, @function
>>> f:
>>> .LFB0:
>>>       .cfi_startproc
>>>       leaq    18(,%rdi,4), %rax
>>>       pushq    %rbp
>>>       .cfi_def_cfa_offset 16
>>>       .cfi_offset 6, -16
>>>       subq    $1, %rdi
>>>       andq    $-16, %rax
>>>       movq    %rsp, %rbp
>>>       .cfi_def_cfa_register 6
>>>       subq    %rax, %rsp
>>>       movl    $123, (%rsp,%rdi,4)
>>>       leave
>>>       .cfi_def_cfa 7, 8
>>>       ret
>>>       .cfi_endproc
>>> .LFE0:
>>>       .size    f, .-f
>>>       .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>>>       .section    .note.GNU-stack,"",@progbits
>
>> Yes, this is against optimisations as you use volatile...
>
> I use volatile to prevent the compiler from optimizing away the
> function body.
"
Linus Torvalds has expressed his displeasure in the past over VLA usage
for arrays with predetermined small sizes, with comments like "USING
VLA'S IS ACTIVELY STUPID! It generates much more code, and much slower
code (and more fragile code), than just using a fixed key size would
have done." [6] With the Linux 4.20 kernel, Linux kernel is effectively
VLA-free.[7] 
"

-- 
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi 
bili naoruzani. -- Mladen Gogala

[toc] | [prev] | [next] | [standalone]


#146524

FromDavid Brown <david.brown@hesbynett.no>
Date2019-10-02 10:01 +0200
Message-ID<qn1lhf$bsm$1@dont-email.me>
In reply to#146518
On 02/10/2019 06:36, Melzzzzz wrote:
> On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>>
>>>> #include <stddef.h>
>>>>
>>>> void f( size_t s )
>>>> {
>>>> 	int volatile a[s];
>>>> 	a[s - 1] = 123;
>>>> }
>>>>
<snip>
>>
>>> Yes, this is against optimisations as you use volatile...
>>
>> I use volatile to prevent the compiler from optimizing away the
>> function body.

There are usually better ways to get this, such as giving a return value
that depends on the function inputs.  If you have to use "volatile" to
ensure you are generating code that can be examined, then minimise its
use rather than making the whole array volatile.

(In a test function that used the VLA for calculations, gcc still
generated a "leave" instruction.)

> "
> Linus Torvalds has expressed his displeasure in the past over VLA usage
> for arrays with predetermined small sizes, with comments like "USING
> VLA'S IS ACTIVELY STUPID! It generates much more code, and much slower
> code (and more fragile code), than just using a fixed key size would
> have done." [6] With the Linux 4.20 kernel, Linux kernel is effectively
> VLA-free.[7] 
> "
> 

VLA's with pre-determined small sizes result in /identical/ code to
arrays with fixed sizes.

void foo1(void) {
	const int arr_size = 12;
	int arr[arr_size];
	...
}

void foo2(void) {
	#define ARR_SIZE 12
	int arr[ARR_SIZE];
	...
}


"foo1" has a VLA with a predetermined small size, while "foo2" has a
normal array with fixed size.  These are different as far as the C
language is concerned, but identical in the generated code.


I /think/ what Torvalds is trying to say is that if you know that the
size "n" of your VLA is going be at most "max_n", and you know "max_n"
is small, then you should use a fixed size array of size "max_n" instead
of a VLA.  I believe that has both advantages and disadvantages.  When
the array is of fixed size (i.e., known at compile time - even if it is
technically a VLA) the code for allocating and deallocating the space is
simpler.  Code for accessing the contents of the array or other data
might be a little simpler.  But it is all just one-time calculations.
Code that is run repeatedly - and if you have an array, you probably
have a loop - is going to be identical.

So you get the trade-off between a few extra instructions for the
variable VLA, balanced against the benefits of reduced cache use from a
smaller array.  I'd not like to be categorical about which is best - it
would need measuring.


If the VLA is making the code fragile, then I expect it would be equally
fragile with a fixed size array.


(Fixed size arrays are also easier for analysis of stack usage, if that
is important.)

[toc] | [prev] | [next] | [standalone]


#146521

FromMelzzzzz <Melzzzzz@zzzzz.com>
Date2019-10-02 04:42 +0000
Message-ID<4VVkF.657428$t92.267489@fx25.am4>
In reply to#146517
On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>
>>> #include <stddef.h>
>>>
>>> void f( size_t s )
>>> {
>>> 	int volatile a[s];
>>> 	a[s - 1] = 123;
>>> }
>>>
>>>
>>>       .file    "x.c"
>>>       .text
>>>       .p2align 4,,15
>>>       .globl    f
>>>       .type    f, @function
>>> f:
>>> .LFB0:
>>>       .cfi_startproc
>>>       leaq    18(,%rdi,4), %rax
>>>       pushq    %rbp
>>>       .cfi_def_cfa_offset 16
>>>       .cfi_offset 6, -16
>>>       subq    $1, %rdi
>>>       andq    $-16, %rax
>>>       movq    %rsp, %rbp
>>>       .cfi_def_cfa_register 6
>>>       subq    %rax, %rsp
>>>       movl    $123, (%rsp,%rdi,4)
>>>       leave
>>>       .cfi_def_cfa 7, 8
>>>       ret
>>>       .cfi_endproc
>>> .LFE0:
>>>       .size    f, .-f
>>>       .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>>>       .section    .note.GNU-stack,"",@progbits
>
>> Yes, this is against optimisations as you use volatile...
>
> I use volatile to prevent the compiler from optimizing away the
> function body.
Try more realistic example:
float read_val();
float process(int,float*);
float read_and_process(int n)
{
        float vals[n];

            for (int i = 0; i < n; ++i)
                        vals[i] = read_val();

                return process(n, vals);
}

Where is `leave` now?
-- 
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi 
bili naoruzani. -- Mladen Gogala

[toc] | [prev] | [next] | [standalone]


#146525

FromDavid Brown <david.brown@hesbynett.no>
Date2019-10-02 10:10 +0200
Message-ID<qn1m1i$f8t$1@dont-email.me>
In reply to#146521
On 02/10/2019 06:42, Melzzzzz wrote:
> On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>>
>>>> #include <stddef.h>
>>>>
>>>> void f( size_t s )
>>>> {
>>>> 	int volatile a[s];
>>>> 	a[s - 1] = 123;
>>>> }
>>>>
>>>>
>>>>       .file    "x.c"
>>>>       .text
>>>>       .p2align 4,,15
>>>>       .globl    f
>>>>       .type    f, @function
>>>> f:
>>>> .LFB0:
>>>>       .cfi_startproc
>>>>       leaq    18(,%rdi,4), %rax
>>>>       pushq    %rbp
>>>>       .cfi_def_cfa_offset 16
>>>>       .cfi_offset 6, -16
>>>>       subq    $1, %rdi
>>>>       andq    $-16, %rax
>>>>       movq    %rsp, %rbp
>>>>       .cfi_def_cfa_register 6
>>>>       subq    %rax, %rsp
>>>>       movl    $123, (%rsp,%rdi,4)
>>>>       leave
>>>>       .cfi_def_cfa 7, 8
>>>>       ret
>>>>       .cfi_endproc
>>>> .LFE0:
>>>>       .size    f, .-f
>>>>       .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>>>>       .section    .note.GNU-stack,"",@progbits
>>
>>> Yes, this is against optimisations as you use volatile...
>>
>> I use volatile to prevent the compiler from optimizing away the
>> function body.
> Try more realistic example:
> float read_val();
> float process(int,float*);
> float read_and_process(int n)
> {
>         float vals[n];
> 
>             for (int i = 0; i < n; ++i)
>                         vals[i] = read_val();
> 
>                 return process(n, vals);
> }
> 
> Where is `leave` now?
> 

The compiler will use it if it is convenient, and not use it otherwise.
 This sample code /does/ generate "leave" with gcc :

int f(int s )
{
    int a[s];
    for (int i = 0; i < s; i++) a[i] = i;
    int t = 0;
    for (int i = 0; i < s; i++) t += a[i];
    return t;
}

(clang does not generate a "leave" - it generates its usual unrolled
vector monstrosities that are highly efficient for huge loop counts, and
terrible for tiny counts.)


Basically, it seems that "leave" is equivalent to "mov %ebp, %esp" then
"pop %ebp".  If the compiler would otherwise have generated these
instructions, then it uses "leave".  If not, then it doesn't.  "leave"
appears to be marginally more efficient than the separate instructions -
enough so to use it when there is the option, but not enough to go out
of its way to use it.

(The matching "enter" instruction is much slower than manual
manipulation of the registers, and is thus avoided.)

[toc] | [prev] | [next] | [standalone]


#146531

FromMel <mel@zzzzz.com>
Date2019-10-02 15:13 +0200
Message-ID<almarsoft.1283905241101098670@news.albasani.net>
In reply to#146525
On Wed, 2 Oct 2019 10:10:26 +0200, David Brown 
<david.brown@hesbynett.no> wrote:
> On 02/10/2019 06:42, Melzzzzz wrote:
> > On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
> >>>> MSVC and gcc always use LEAVE when you have dynamic 
stack-frames
> >>>> with VLAs (gcc) or alloca(). Here's an example of gcc with 
VLAs:
> >>>>
> >>>> #include <stddef.h>
> >>>>
> >>>> void f( size_t s )
> >>>> {
> >>>> 	int volatile a[s];
> >>>> 	a[s - 1] = 123;
> >>>> }
> >>>>
> >>>>
> >>>>       .file    "x.c"
> >>>>       .text
> >>>>       .p2align 4,,15
> >>>>       .globl    f
> >>>>       .type    f, @function
> >>>> f:
> >>>> .LFB0:
> >>>>       .cfi_startproc
> >>>>       leaq    18(,%rdi,4), %rax
> >>>>       pushq    %rbp
> >>>>       .cfi_def_cfa_offset 16
> >>>>       .cfi_offset 6, -16
> >>>>       subq    $1, %rdi
> >>>>       andq    $-16, %rax
> >>>>       movq    %rsp, %rbp
> >>>>       .cfi_def_cfa_register 6
> >>>>       subq    %rax, %rsp
> >>>>       movl    $123, (%rsp,%rdi,4)
> >>>>       leave
> >>>>       .cfi_def_cfa 7, 8
> >>>>       ret
> >>>>       .cfi_endproc
> >>>> .LFE0:
> >>>>       .size    f, .-f
> >>>>       .ident    "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
> >>>>       .section    .note.GNU-stack,"",@progbits
> >>
> >>> Yes, this is against optimisations as you use volatile...
> >>
> >> I use volatile to prevent the compiler from optimizing away the
> >> function body.
> > Try more realistic example:
> > float read_val();
> > float process(int,float*);
> > float read_and_process(int n)
> > {
> >         float vals[n];
> > 
> >             for (int i = 0; i < n; ++i)
> >                         vals[i] = read_val();
> > 
> >                 return process(n, vals);
> > }
> > 
> > Where is `leave` now?
> > 


> The compiler will use it if it is convenient, and not use it 
otherwise.
>  This sample code /does/ generate "leave" with gcc :


> int f(int s )
> {
>     int a[s];
>     for (int i = 0; i < s; i++) a[i] = i;
>     int t = 0;
>     for (int i = 0; i < s; i++) t += a[i];
>     return t;
> }


> (clang does not generate a "leave" - it generates its usual unrolled
> vector monstrosities that are highly efficient for huge loop 
counts, and
> terrible for tiny counts.)




> Basically, it seems that "leave" is equivalent to "mov %ebp, %esp" 
then
> "pop %ebp".  If the compiler would otherwise have generated these
> instructions, then it uses "leave".  If not, then it doesn't.  
"leave"
> appears to be marginally more efficient than the separate 
instructions -
> enough so to use it when there is the option, but not enough to go 
out
> of its way to use it.


> (The matching "enter" instruction is much slower than manual
> manipulation of the registers, and is thus avoided.)

This is not reallistic example as well.

-- 
Press any key to continue or any other to quit 

[toc] | [prev] | [next] | [standalone]


#146503

FromDavid Brown <david.brown@hesbynett.no>
Date2019-10-01 21:10 +0200
Message-ID<qn08bp$7n0$1@dont-email.me>
In reply to#146499
On 01/10/2019 17:31, Bonita Montero wrote:
>>> The compiler usually uses RPB to remember the frame-pointer-address
>>> at the prolog of the function. EBP is more suitable because it can
>>> be restored in one step by the x86 LEAVE-instruction.
> 
>> So what?  The RSP is restored automatically by the ret instruction.
> 
> Yes, but LEAVE does three instructions in one step. Usually this
> results in the same uOPs, but it is only one slot in the decoder.

I don't know this case, but typically on modern cpus "complex"
instructions like "leave" are slower than manual expanding the
instructions using "pop", "ret", etc.

The easiest way to find out is to do a test compile (godbolt.org is
great for it) making sure you have cpu-specific tuning flags and
optimisations enabled, and look at the output.  The compiler writers
know better than most of us which instruction patterns are the most
efficient.

[toc] | [prev] | [next] | [standalone]


#146506

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-10-01 21:25 +0200
Message-ID<qn096o$3qm$2@news.albasani.net>
In reply to#146503
> I don't know this case, but typically on modern cpus "complex"
> instructions like "leave" are slower than manual expanding the
> instructions using "pop", "ret", etc.

That's wrong.

[toc] | [prev] | [next] | [standalone]


Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6  Next page →

Back to top | Article view | comp.lang.c


csiph-web