* static class member as interrupt handler works, but not if class is templated @ 2021-04-10 13:33 Klaus Rudolph 2021-04-10 15:26 ` Jonathan Wakely 2021-04-12 9:20 ` Peter Sommerlad (C++) 0 siblings, 2 replies; 14+ messages in thread From: Klaus Rudolph @ 2021-04-10 13:33 UTC (permalink / raw) To: gcc-help, avr-gcc-list Hi all, if I write a class with static member function I can use it as an interrupt handler as follows: class Dummy { static void Handler() __asm__("__vector_10") __attribute__((__signal__, __used__, __externally_visible__)); }; void Dummy::Handler() { } I can see the vector is entered in the handler table: 1c: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> 20: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> 24: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> 28: 0c 94 36 00 jmp 0x6c ; 0x6c <__vector_10> 2c: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> 30: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> ################### But if the class becomes a template, the function is not longer entered in the handler. How can I fix it? template < int i > class Dummy { static void Handler() __asm__("__vector_10") __attribute__((__signal__, __used__, __externally_visible__)); }; template < int i> void Dummy<i>::Handler() { } Dummy<1> d1; 20: 0c 94 3c 00 jmp 0x78 ; 0x78 <__bad_interrupt> 24: 0c 94 3c 00 jmp 0x78 ; 0x78 <__bad_interrupt> 28: 0c 94 3c 00 jmp 0x78 ; 0x78 <__bad_interrupt> 2c: 0c 94 3c 00 jmp 0x78 ; 0x78 <__bad_interrupt> 30: 0c 94 3c 00 jmp 0x78 ; 0x78 <__bad_interrupt> I tried it with avr-g++ (Fedora 10.2.0-1.fc33) 10.2.0 Thanks! ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-10 13:33 static class member as interrupt handler works, but not if class is templated Klaus Rudolph @ 2021-04-10 15:26 ` Jonathan Wakely 2021-04-10 19:36 ` Trampas Stern 2021-04-10 20:11 ` Klaus 2021-04-12 9:20 ` Peter Sommerlad (C++) 1 sibling, 2 replies; 14+ messages in thread From: Jonathan Wakely @ 2021-04-10 15:26 UTC (permalink / raw) To: Klaus Rudolph; +Cc: gcc-help, avr-gcc-list On Sat, 10 Apr 2021, 15:07 Klaus Rudolph via Gcc-help, <gcc-help@gcc.gnu.org> wrote: > Hi all, > > if I write a class with static member function I can use it as an > interrupt handler as follows: > > class Dummy > { > static void Handler() __asm__("__vector_10") > __attribute__((__signal__, __used__, __externally_visible__)); > }; > > void Dummy::Handler() > { > > } > > I can see the vector is entered in the handler table: > > > > 1c: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> > 20: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> > 24: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> > 28: 0c 94 36 00 jmp 0x6c ; 0x6c <__vector_10> > 2c: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> > 30: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> > > ################### > > But if the class becomes a template, the function is not longer entered > in the handler. How can I fix it? > > template < int i > > class Dummy > { > static void Handler() __asm__("__vector_10") > __attribute__((__signal__, __used__, __externally_visible__)); > }; > > template < int i> > void Dummy<i>::Handler() > { > > } > > Dummy<1> d1; > This doesn't cause the instantiation of the member function. Have you tried an explicit instantiation? template class Dummy<1>; ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-10 15:26 ` Jonathan Wakely @ 2021-04-10 19:36 ` Trampas Stern 2021-04-10 20:11 ` Klaus 1 sibling, 0 replies; 14+ messages in thread From: Trampas Stern @ 2021-04-10 19:36 UTC (permalink / raw) To: Jonathan Wakely; +Cc: Klaus Rudolph, gcc-help, avr-gcc-list I wish there was a better way to interrupt handlers in classes, for embedded. For example I write a UART class as a driver which I initialize by passing a pointer to hardware address. However because different UARTs use different interrupt vectors I end up having to have the extern C and create each handler which then I have to register a callback for the handler to call the correct method in class instance. If you guys have a better way I would love to know. Thanks Trampas On Sat, Apr 10, 2021 at 11:26 AM Jonathan Wakely <jwakely.gcc@gmail.com> wrote: > > > On Sat, 10 Apr 2021, 15:07 Klaus Rudolph via Gcc-help, < > gcc-help@gcc.gnu.org> wrote: > >> Hi all, >> >> if I write a class with static member function I can use it as an >> interrupt handler as follows: >> >> class Dummy >> { >> static void Handler() __asm__("__vector_10") >> __attribute__((__signal__, __used__, __externally_visible__)); >> }; >> >> void Dummy::Handler() >> { >> >> } >> >> I can see the vector is entered in the handler table: >> >> >> >> 1c: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> >> 20: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> >> 24: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> >> 28: 0c 94 36 00 jmp 0x6c ; 0x6c <__vector_10> >> 2c: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> >> 30: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> >> >> ################### >> >> But if the class becomes a template, the function is not longer entered >> in the handler. How can I fix it? >> >> template < int i > >> class Dummy >> { >> static void Handler() __asm__("__vector_10") >> __attribute__((__signal__, __used__, __externally_visible__)); >> }; >> >> template < int i> >> void Dummy<i>::Handler() >> { >> >> } >> >> Dummy<1> d1; >> > > This doesn't cause the instantiation of the member function. > > Have you tried an explicit instantiation? > > template class Dummy<1>; > > > > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-10 15:26 ` Jonathan Wakely 2021-04-10 19:36 ` Trampas Stern @ 2021-04-10 20:11 ` Klaus 2021-04-11 12:21 ` David Brown 1 sibling, 1 reply; 14+ messages in thread From: Klaus @ 2021-04-10 20:11 UTC (permalink / raw) To: Jonathan Wakely; +Cc: gcc-help, avr-gcc-list Hi, Am 10.04.21 um 17:26 schrieb Jonathan Wakely: > > Dummy<1> d1; > > > This doesn't cause the instantiation of the member function. > > Have you tried an explicit instantiation? > > template class Dummy<1>; Did not change anything. If I use my original code, I get the instantiation of the function: 0000007e <Dummy<1>::Handler()>: 7e: 18 95 reti But it is simply not named as "__vector_10" which is the problem. The member function is instantiated but still with wrong name even with my or your code. Klaus ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-10 20:11 ` Klaus @ 2021-04-11 12:21 ` David Brown 2021-04-11 23:33 ` Trampas Stern 0 siblings, 1 reply; 14+ messages in thread From: David Brown @ 2021-04-11 12:21 UTC (permalink / raw) To: Klaus, Jonathan Wakely; +Cc: gcc-help, avr-gcc-list On 10/04/2021 22:11, Klaus via Gcc-help wrote: > Hi, > > > > Am 10.04.21 um 17:26 schrieb Jonathan Wakely: > >> >> Dummy<1> d1; >> >> >> This doesn't cause the instantiation of the member function. >> >> Have you tried an explicit instantiation? >> >> template class Dummy<1>; > > Did not change anything. > > If I use my original code, I get the instantiation of the function: > > 0000007e <Dummy<1>::Handler()>: > 7e: 18 95 reti > > But it is simply not named as "__vector_10" which is the problem. The > member function is instantiated but still with wrong name even with my > or your code. > > Klaus > > To my knowledge, there isn't a better way than to make specific dedicated stand-alone functions: static void Handler_1() __asm__("__vector_10") __attribute__((__signal__, __used__, __externally_visibile__)) { Dummy<1>::Handler(); } For device drivers like that, you have a specific number of instantiations that match the number of peripherals on the particular microcontroller. And they each have different vectors. There really isn't any other better way, to my knowledge. (You can use a bit of pre-processing macros and conditional compilation to automate it a bit, generating as many of these functions as there are UARTs or whatever defined in the device header files for the microcontroller.) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-11 12:21 ` David Brown @ 2021-04-11 23:33 ` Trampas Stern 0 siblings, 0 replies; 14+ messages in thread From: Trampas Stern @ 2021-04-11 23:33 UTC (permalink / raw) To: David Brown; +Cc: Klaus, Jonathan Wakely, gcc-help, avr-gcc-list In C++ for interrupt vectors in drivers I set up an array of pointers to function all the peripheral driver code like this for timer counters. static voidCallback_t _isr_funcs[TC_INST_NUM]={NULL}; Then in each handler if the pointer is not null I call it. This is a lot of work and overhead but it works. On Sun, Apr 11, 2021 at 8:21 AM David Brown <david.brown@hesbynett.no> wrote: > On 10/04/2021 22:11, Klaus via Gcc-help wrote: > > Hi, > > > > > > > > Am 10.04.21 um 17:26 schrieb Jonathan Wakely: > > > >> > >> Dummy<1> d1; > >> > >> > >> This doesn't cause the instantiation of the member function. > >> > >> Have you tried an explicit instantiation? > >> > >> template class Dummy<1>; > > > > Did not change anything. > > > > If I use my original code, I get the instantiation of the function: > > > > 0000007e <Dummy<1>::Handler()>: > > 7e: 18 95 reti > > > > But it is simply not named as "__vector_10" which is the problem. The > > member function is instantiated but still with wrong name even with my > > or your code. > > > > Klaus > > > > > > To my knowledge, there isn't a better way than to make specific > dedicated stand-alone functions: > > static void Handler_1() __asm__("__vector_10") > __attribute__((__signal__, __used__, __externally_visibile__)) > { > Dummy<1>::Handler(); > } > > For device drivers like that, you have a specific number of > instantiations that match the number of peripherals on the particular > microcontroller. And they each have different vectors. There really > isn't any other better way, to my knowledge. (You can use a bit of > pre-processing macros and conditional compilation to automate it a bit, > generating as many of these functions as there are UARTs or whatever > defined in the device header files for the microcontroller.) > > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-10 13:33 static class member as interrupt handler works, but not if class is templated Klaus Rudolph 2021-04-10 15:26 ` Jonathan Wakely @ 2021-04-12 9:20 ` Peter Sommerlad (C++) 2021-04-12 11:16 ` Klaus Rudolph 1 sibling, 1 reply; 14+ messages in thread From: Peter Sommerlad (C++) @ 2021-04-12 9:20 UTC (permalink / raw) To: Klaus Rudolph; +Cc: gcc-help, avr-gcc-list Klaus, I do not have a solution, but I try to be helpful and give a list what I would try to understand the situation: - why is the special name __vector_10 used to get the function address into the interrupt table? Is there another way, or is the environment insisting on such a name? Can you change the linker (i.e. with a dedicated map file) to get the Dummy<i>::Handler into the table. - Is the static Handler() function dependent on the template parameter? If not, you can put it into a base class of the class template. - what is the means that a function is considered to be an interrupt handler? What does the tooling do between the compiler generating object code and the binary that ends up in flash? How does it work? - 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 what I have in the top of my head at the moment. In the end, you might need to either change the tools or their configuration to get what you want. Regards Peter. Klaus Rudolph wrote on 10.04.21 15:33: > Hi all, > > if I write a class with static member function I can use it as an > interrupt handler as follows: > > class Dummy > { > static void Handler() __asm__("__vector_10") > __attribute__((__signal__, __used__, __externally_visible__)); > }; > > void Dummy::Handler() > { > > } > > I can see the vector is entered in the handler table: > > > > 1c: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> > 20: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> > 24: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> > 28: 0c 94 36 00 jmp 0x6c ; 0x6c <__vector_10> > 2c: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> > 30: 0c 94 34 00 jmp 0x68 ; 0x68 <__bad_interrupt> > > ################### > > But if the class becomes a template, the function is not longer entered > in the handler. How can I fix it? > > template < int i > > class Dummy > { > static void Handler() __asm__("__vector_10") > __attribute__((__signal__, __used__, __externally_visible__)); > }; > > template < int i> > void Dummy<i>::Handler() > { > > } > > Dummy<1> d1; > > 20: 0c 94 3c 00 jmp 0x78 ; 0x78 <__bad_interrupt> > 24: 0c 94 3c 00 jmp 0x78 ; 0x78 <__bad_interrupt> > 28: 0c 94 3c 00 jmp 0x78 ; 0x78 <__bad_interrupt> > 2c: 0c 94 3c 00 jmp 0x78 ; 0x78 <__bad_interrupt> > 30: 0c 94 3c 00 jmp 0x78 ; 0x78 <__bad_interrupt> > > > I tried it with avr-g++ (Fedora 10.2.0-1.fc33) 10.2.0 > > Thanks! > > > -- Peter Sommerlad Better Software: Consulting, Training, Reviews Modern, Safe & Agile C++ peter.cpp@sommerlad.ch +41 79 432 23 32 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-12 9:20 ` Peter Sommerlad (C++) @ 2021-04-12 11:16 ` Klaus Rudolph 2021-04-12 11:53 ` Matthijs Kooijman 0 siblings, 1 reply; 14+ messages in thread From: Klaus Rudolph @ 2021-04-12 11:16 UTC (permalink / raw) To: Peter Sommerlad (C++); +Cc: gcc-help, avr-gcc-list Hi, Am 12.04.21 um 11:20 schrieb Peter Sommerlad (C++): > - why is the special name __vector_10 used to get the function address > into the interrupt table? Is there another way, or is the environment > insisting on such a name? Can you change the linker (i.e. with a > dedicated map file) to get the Dummy<i>::Handler into the table. Currently the library (avr-libc) has a interrupt vector table which simple uses the names __vector_xx. The linker collects all functions with this naming conventions and replace the function address in that table. > > - Is the static Handler() function dependent on the template parameter? > If not, you can put it into a base class of the class template. Yes, if not, it can be omitted, quite clear. > > - what is the means that a function is considered to be an interrupt > handler? What does the tooling do between the compiler generating object > code and the binary that ends up in flash? How does it work? The attribute for an interrupt handler added to a function adds the following to the code of the function: Save all registers .. normal function content ... restore all registers use "reti" instead of "ret" for returning to the "calling context". > > - 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! > In the end, you might need to either change the tools or their > configuration to get what you want. I was in hope, that I did something wrong or a workaround is known to this problem. If that is not the case, I can fix the compiler, change the linker, modify the avr-libc... yes. But in all this cases, I will still use C style handlers for this purpose. It is uggly, but C++ on AVR is always ugly ( v-table in RAM, jump for switch case in RAM, no STL support ). If someone can point me to the "problem" inside the compiler, I can give it a try, but it seems to be the long way :-) But maybe a funny one and helpful for others. In general: Why assigning attributes to member functions in templated class context fails? For me it looks like a bug. Klaus ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-12 11:16 ` Klaus Rudolph @ 2021-04-12 11:53 ` Matthijs Kooijman 2021-04-12 12:12 ` Klaus Rudolph 0 siblings, 1 reply; 14+ messages in thread From: Matthijs Kooijman @ 2021-04-12 11:53 UTC (permalink / raw) To: Klaus Rudolph; +Cc: Peter Sommerlad (C++), gcc-help, avr-gcc-list [-- Attachment #1: Type: text/plain, Size: 1921 bytes --] > > - 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. 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. 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). Maybe not as nice and self-contained as the asm attribute, but it does allow multiple instantiations (where the global function defines which instantiation is going to be used for the ISR). Gr. Matthijs [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-12 11:53 ` Matthijs Kooijman @ 2021-04-12 12:12 ` Klaus Rudolph 2021-04-12 13:46 ` David Brown 2021-04-12 14:25 ` Anton Staaf 0 siblings, 2 replies; 14+ messages in thread From: Klaus Rudolph @ 2021-04-12 12:12 UTC (permalink / raw) To: Peter Sommerlad (C++), gcc-help, avr-gcc-list 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. 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 :-) > 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 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-12 12:12 ` Klaus Rudolph @ 2021-04-12 13:46 ` David Brown 2021-04-12 14:56 ` Klaus Rudolph 2021-04-12 14:25 ` Anton Staaf 1 sibling, 1 reply; 14+ messages in thread From: David Brown @ 2021-04-12 13:46 UTC (permalink / raw) To: Klaus Rudolph, Peter Sommerlad (C++), gcc-help, avr-gcc-list 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 > > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-12 13:46 ` David Brown @ 2021-04-12 14:56 ` Klaus Rudolph 0 siblings, 0 replies; 14+ messages in thread From: Klaus Rudolph @ 2021-04-12 14:56 UTC (permalink / raw) To: David Brown, Peter Sommerlad (C++), gcc-help, avr-gcc-list Am 12.04.21 um 15:46 schrieb David Brown: > 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. You don't have to be worry about. If it is instantiated zero times, nothing happens, if it instantiates once, it gets the new name, if it instantiates multiple times, it get multiple instances with the same name and fails during linking. Absolutely fine! > > 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. There should be anything combined. The templated instance simply should have the name from asm statement which has C linkage. > > 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. The opposite is meant! It is intended by using the asm statement that we have a single name, fully independent of parameters for the template. Klaus ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-12 12:12 ` Klaus Rudolph 2021-04-12 13:46 ` David Brown @ 2021-04-12 14:25 ` Anton Staaf 2021-04-12 15:06 ` Klaus Rudolph 1 sibling, 1 reply; 14+ messages in thread From: Anton Staaf @ 2021-04-12 14:25 UTC (permalink / raw) To: Klaus Rudolph; +Cc: Peter Sommerlad (C++), gcc-help, avr-gcc-list Klaus, I'm not sure if my previous answer didn't make it through or was just missed, but I believe your problem is related to this GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435 -Anton On Mon, Apr 12, 2021 at 5:14 AM Klaus Rudolph <lts-rudolph@gmx.de> 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. > > 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 :-) > > > 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 > > > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: static class member as interrupt handler works, but not if class is templated 2021-04-12 14:25 ` Anton Staaf @ 2021-04-12 15:06 ` Klaus Rudolph 0 siblings, 0 replies; 14+ messages in thread From: Klaus Rudolph @ 2021-04-12 15:06 UTC (permalink / raw) To: Anton Staaf; +Cc: Peter Sommerlad (C++), gcc-help, avr-gcc-list Am 12.04.21 um 16:25 schrieb Anton Staaf: > Klaus, I'm not sure if my previous answer didn't make it through or was > just missed, but I believe your problem is related to this GCC bug: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435 > <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435> Yes, looks related! Thanks! No idea if the [[attribute]] thing is internally walking the same path as the "asm" attribute. But it looks that template stuff is not taking part in both actions. But as we can see: The bug is from Feb 2016 and multiple times confirmed until 2019... and after that we see some started to do something but runs into trouble... last mail from Nov 2019... Seems to be that there is no chance to get it working as also the experts are running against a wall. OK, we have to live with it.... Maybe someone else have a chance to take a look on it? Thanks Klaus ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2021-04-12 15:06 UTC | newest] Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-04-10 13:33 static class member as interrupt handler works, but not if class is templated Klaus Rudolph 2021-04-10 15:26 ` Jonathan Wakely 2021-04-10 19:36 ` Trampas Stern 2021-04-10 20:11 ` Klaus 2021-04-11 12:21 ` David Brown 2021-04-11 23:33 ` Trampas Stern 2021-04-12 9:20 ` Peter Sommerlad (C++) 2021-04-12 11:16 ` Klaus Rudolph 2021-04-12 11:53 ` Matthijs Kooijman 2021-04-12 12:12 ` Klaus Rudolph 2021-04-12 13:46 ` David Brown 2021-04-12 14:56 ` Klaus Rudolph 2021-04-12 14:25 ` Anton Staaf 2021-04-12 15:06 ` Klaus Rudolph
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).