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 1A62D3850400 for ; Mon, 12 Apr 2021 13:46:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 1A62D3850400 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=hesbynett.no Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=david.brown@hesbynett.no Received: from [192.168.0.63] (unknown [79.161.10.130]) by spam02.hesby.net (Halon) with ESMTPSA id 82d813dc-9b95-11eb-9b5d-506b8dfa0e58; Mon, 12 Apr 2021 15:46:43 +0200 (CEST) Subject: Re: static class member as interrupt handler works, but not if class is templated To: Klaus Rudolph , "Peter Sommerlad (C++)" , "gcc-help@gcc.gnu.org" , avr-gcc-list@nongnu.org References: <5f39cb4e-a445-bf19-ae90-b76c934aa930@gmx.de> <38829120-5ab7-d74e-0149-edf8ec6d4227@sommerlad.ch> <20210412115337.GB250@login.tika.stderr.nl> From: David Brown Message-ID: Date: Mon, 12 Apr 2021 15:46:41 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=windows-1252 Content-Language: en-GB Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-3032.8 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, NICE_REPLY_A, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-help@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-help mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 Apr 2021 13:46:48 -0000 On 12/04/2021 14:12, Klaus Rudolph via Gcc-help wrote: > Am 12.04.21 um 13:53 schrieb Matthijs Kooijman: >>>> - figure out, where the special handling of the __vector_10 seems to >>>> happen, and why it is not happening in the class template case. This >>>> might help diagnose if and where to fix it within the compiler. >>> >>> That is compiler internals... yes, if it is a compiler bug, it is the >>> way to have a solution. But in that case, it seems to be a generic >>> problem for gcc as attributes are not assigned to any templated class >>> member functions. No idea if this is related to the target ( avr ) or >>> generic for all platforms. But I never did any change inside the >>> compiler. Any help is welcome! >> >> My suspiciou would be that this is a generic gcc problem, where the >> "asm" attribute is not honoured for template functions. It probably also >> makes some sense, since a template is intended to be instantiated >> multiple times, and each instantiation gets a name that is generated >> based on (I believe) the template arguments passed, so I suspect that >> the "generate a name for this template instantiation" code doesn't look >> at the asm attribute. >> >> Also note that *if* it would, then each instantiation would use the same >> name and multiple instanations would result in duplicate symbols. If you >> would bring this up as a gcc bug, I wouldn't be surprised that it would >> be closed as wontfix for this reason. > > I disagree as a template "always" would be instantiated multiple times. > And even if it would be, the linker will fire a error message, as it > sees multiple definitions. So there is no "general" problem in > "renaming" a templated function. It simply *can* work. Certainly templates can be instantiated zero, once, or multiple times. And certainly some templates are intended only to be instantiated a single time. But it would surely be difficult to have a feature that only works when there is a single instantiation. There is also the issue of linkage of the names here. A template instantiation has function/method names that are mangled with the template type, template parameters, parameter types, etc. These have a particular kind of linkage that lets the toolchain (compiler, assembler and linker) know that they can be defined in more than one unit, and at link time one of them (by unspecified choice) can be picked for the final binary. An assembly-defined specific name for an interrupt vector, on the other hand, is a C external linkage name that can only be defined once. I don't see that these two uses could easily be combined. It seems natural to me that a feature which can only be relevant to a single instantiation of a template should be connected to an instantiation, not a definition. This is particularly true when the details of the attribute you want - the "vector" assembly name - are dependent on a non-type parameter for the template. > > But it looks that not only the "renaming" stuff did not work, all the > flags are not handled with the templated function. Looks like that the > asm declaration did not find its target :-) > >> >> Another workaround that I think hasn't been suggested yet, would be to >> just define a global `__vector_10` function and from that just call your >> templated static member. > > That is the classical way "we" all work. And it optimizes well in that > case as the code from the static templated member is fully inlined. But > it is still a workaround and it simply breaks standard c++ coding. Yes, > we can write C with classes, but I simply dislike :-) > Unfortunately, C++ can't do everything - even with gcc extensions. There are all sorts of things that could be useful to have, but simply are not practical or possible to implement. One that I would like is a way to have a class or template instantiation that is at file/namespace scope, but which is constructed before first use rather than before main() starts. But it should not have the overhead of run-time checks or indirect access (so no static class member). I think it is fair to say it is not going to happen - so I need manual "init" functions with lists of "init" method calls for each object. >> Combined with the `always_inline` attribute, >> you can ensure that the call is inlined and there is no runtime overhead >> (with LTO, this probably already happens when there's just a single call >> to the member). > > It already optimizes well in O2 if templated member function and free > handler definition is in same translation unit. > > Klaus > >