From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from spam02.hesby.net (spam01.hesby.net [81.29.32.152]) by sourceware.org (Postfix) with ESMTP id 524FC3858284 for ; Wed, 29 Nov 2023 11:52:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 524FC3858284 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=hesbynett.no Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=hesbynett.no ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 524FC3858284 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=81.29.32.152 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701258770; cv=none; b=so+JBJBcjHZA84ntIeDdpz0GADnuzohen3bCZ7tZ10fvzR5jeBqnUFD2JYPaZbdZ2qBQ+6Es12W9M302dOI6mqI0Tfeo46IeumbNfT6WIOcqbDEJggfeLmnSdDC+XqIygSPAu8NWZ3kwGxKyDev0iqRZUb/65iFk8op7zfUO5K0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701258770; c=relaxed/simple; bh=61Jvw4WWyThouC5hBFFafSv4uVLdvb/wRI8mMmBHkXc=; h=Message-ID:Date:MIME-Version:Subject:To:From; b=SyoLApmYjDJTkUSEAUmcwNNozHDcwxsr48wtiI5PcU3LjxY9UHjbZu6tcmxOqyUI3OXADyP0NslvdbnOzTcPSzbWYemtTXbvDHwpAmekmbduBJeaU3mpd9iHPQXE8FxVJIeM8my/F7Wajbrh2trnBzsp3/vLnBpqAV7UsQ9krAE= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from [192.168.0.63] (unknown [79.161.10.130]) by spam02.hesby.net (Halon) with ESMTPSA id cdf75737-8ead-11ee-b387-506b8dfa0e58; Wed, 29 Nov 2023 12:52:45 +0100 (CET) Message-ID: Date: Wed, 29 Nov 2023 12:52:43 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 Subject: Re: arm-none-eabi, nested function trampolines and caching Content-Language: en-GB To: Matthias Pfaller , edd.robbins@gmail.com, gcc-help@gcc.gnu.org Cc: Ed Robbins References: <8342aeef-4eef-231b-bf45-416660954fdb@marco.de> <54f5aefe-8dad-2f97-f06e-d08020396a5f@marco.de> From: David Brown In-Reply-To: <54f5aefe-8dad-2f97-f06e-d08020396a5f@marco.de> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3032.5 required=5.0 tests=BAYES_00,BODY_8BITS,KAM_DMARC_STATUS,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 29/11/2023 08:50, Matthias Pfaller wrote: > On 2023-11-28 19:00, David Brown wrote: > > Can I ask (either or both of you) why you are using are using nested > functions like > > this?  This is possibly the first time I have heard of anyone using > them, certainly > > the first time in embedded development. Even when I programmed in > Pascal, where > > nested functions are part of the language, I did not use them more > than a couple of > > times. > > > > What benefit do you see in nested functions in C, compared to having > separate > > functions?  Have you considered moving to C++ and using lambdas, > which are more > > flexible, standard, and can be very much more efficient? > > > > This is, of course, straying from the topicality of this mailing > list. But I am > > curious, and I doubt if I am the only one who is. > > - I'm maintaining our token threaded forth interpreter. In the inner > loop there is a absurdly big switch for the primitives. I'm loading rp, > sp and tos into local variables. pushing, popping  and memory access is > done by nested functions (checking for stack over and under flows, > managing tos, access violations, ...). Of course that could be done by > macros. But when I'm calling C-functions from within the switch I'll > sometimes pass pointers to the local functions (e.g. for catch/throw > exception handling). > > - When calling list iterators, I'm sometimes passing references to > nested functions > > - When locking is necessary and the function has multiple return points > I'm doing something like: > > void somefunction(void) > { >   void f(void) >   { >      ... >   } >   lock(); >   f(); >   unlock(); > } > > I know, in a lot of cases I could just define some outer static function > or use gotos. But to my eye it just looks nicer that way. In most cases > there will be no trampoline necessary anyway. Its not used that often > and we could probably get rid of it in most cases by using macros and ({ > ... }). > Thanks for that. I can appreciate that local functions can look nicer than macros or goto spaghetti. In simple cases (which is probably the majority for your usage), the local functions will be inlined and will give pretty much exactly the same code as you'd get for macros, outer static functions, or other methods. But I'd be very unhappy to see trampolines here, as you will need for more complicated cases. The overheads are not something you'd want to see in the inner loop of an interpreter. AFAIUI, the reason the compiler has to generate trampolines here is to make a function that has access to some of the local variables, while being shoe-horned into the appearance of a function with parameters that don't include any extra values or references. If you were, as an alternative, to switch to C++ and use lambdas instead of nested functions that all disappears precisely because lambdas do not have to be forced to match the function signature - the generated lambda can take extra hidden parameters (and even extra hidden state) as needed. Of course it's never easy to change these kinds of things in existing code. And it is particularly difficult to get solutions that work efficiently on a wide range of compilers or versions. David