Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread Bruce D. Lightner

David,

Good points.  As you probably are aware, avr-gcc interrupt handlers are 
very special things.  The generated code saves a minimal set of 
processor state (i.e., registers) in entry. Calling an external function 
forces the compiler to save "everything" to preserve the avr-gcc 
"execution model" (https://gcc.gnu.org/wiki/avr-gcc), which, for 
example, assumes that R1 always contains the constant zero.


For a C++ interrupt handler to work in all cases those rules need to be 
headed.  And, in-line assembly statements can easily "break" the 
required execution model.  Ask me how I know! :-)


Later AVR microcontrollers with hardware support for divide added a 
status bit to SREG that needed to be saved/restored.  That's one of the 
reasons one needs to set the "machine type" correctly when using avr-gcc.


Best regards,
Bruce D. Lightner
Lightner Engineering
La Jolla, California
light...@lightner.net
https://www.linkedin.com/in/brucedlightner/


On 4/12/2021 6:49 AM, David Kelly wrote:

All of this might not be a bug at all but an undefined work around for 
deficiencies in C++ primitive functions in the avr-gcc support library? To 
prevent one from using?

In the early days of avr-gcc, just plain C, not all support primitive functions 
were reentrant. If memory serves me, math functions on longs were dangerous. 
That not all registers were stacked on entry to the interrupt handler (that 
would be costly) and the compiler (and support library) assumed some registers 
were free to use without preserving across function calls.

--
David Kelly N4HHE, dke...@hiwaay.net

Whom computers would destroy, they must first drive mad.






Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread Klaus Rudolph

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



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



Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread Klaus Rudolph

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



Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread 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

-Anton


On Mon, Apr 12, 2021 at 5:14 AM Klaus Rudolph  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
>
>
>


Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread David Kelly
All of this might not be a bug at all but an undefined work around for 
deficiencies in C++ primitive functions in the avr-gcc support library? To 
prevent one from using?

In the early days of avr-gcc, just plain C, not all support primitive functions 
were reentrant. If memory serves me, math functions on longs were dangerous. 
That not all registers were stacked on entry to the interrupt handler (that 
would be costly) and the compiler (and support library) assumed some registers 
were free to use without preserving across function calls.

--
David Kelly N4HHE, dke...@hiwaay.net

Whom computers would destroy, they must first drive mad.




Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread David Brown
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
> 
> 




Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread Klaus Rudolph

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




Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread 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.

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


signature.asc
Description: PGP signature


Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread Klaus Rudolph

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::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



Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread Peter Sommerlad (C++)

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::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::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@sommerlad.ch
+41 79 432 23 32



Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread David Brown
On 12/04/2021 10:46, Klaus Rudolph wrote:
> Thank you all so much for wasting my thread!
> 
> Please do NOT answer, you all produced enough spam! Would be nice if
> someone can help on *MY* topic!
> 
> Thanks!
> 

Sorry, but that is not the way mailing lists or other public discussion
mediums work.  You don't own a thread.  You can /start/ a thread, and if
people are willing and able to give you help or advice, it's good that
they do so.  (You may note that several, including both Trampas and me,
have given suggestions - basically, there is no known ideal way to do
what you would like.)

However, you don't control a thread, and if it drifts and inspires new
discussions, that is a good thing as long as the posts are reasonably
topical for the list.

And please do not accuse people of producing spam until you understand
what the term "spam" means.  There has been no spam in this thread.

If you have any direct comments to the help you have been given so far,
then I am sure people will continue to discuss on that branch of the thread.



Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread Klaus Rudolph

Thank you all so much for wasting my thread!

Please do NOT answer, you all produced enough spam! Would be nice if
someone can help on *MY* topic!

Thanks!



Re: static class member as interrupt handler works, but not if class is templated

2021-04-12 Thread David Brown
Hi,

C++ is a language designed to be used with optimising compilers.
Turning off optimisations cripples it - either you end up with so
absurdly poor object code that you massively change the timing, and
therefore behaviour, of your embedded system, or you have to limit
yourself drastically in the kind of C++ you write.  With the templates I
have used for IO pin control (on a different target), unoptimised code
can mean hundreds of instructions for simple port access - using -O1
gives the expected two or three instructions.

It is extremely rare that I find -O0 useful for any purpose.  -O1 is the
lowest I use, when doing complex debugging (as it avoids many of the
code re-organisations of the higher levels I normally use).  Assembly
level debugging in particular is impossible with -O0 as you can't see
what is going on for all the register and stack movements.  (This
applies equally to C and C++.)

A lot of C++ code makes heavy use of functions that "disappear" - code
that manipulates types rather than values, which are very useful to the
aim of having the compiler help check the correctness of code but which
you do not want as object-code functions.

A lot of C++ has functions that have no name as such, or where the same
source code produces multiple object code functions (generated from
templates, lambdas, etc.) that are difficult when you want to put
breakpoints.  It is not impossible, but it can be less convenient - and
sometimes you need to add artificial points (setting volatile variables,
adding "no_inline" attributes, etc.) to help.  (This applies to C too,
but more so to C++.)


When optimising, all bets are /not/ off.  It is often entirely possible
to know roughly how the compiler will generate code for optimised C or
C++.  On the other hand, it is often hard to tell what code will be
generated for some code whether it is C or C++, optimised or not.  This
depends very much on the code in question, not the programming language.

People who use C "because they know exactly what code the compiler
produces" and think there is a one-to-one correspondence between C
source and object code are simply wrong.  If they need such a
correspondence between source and object code, assembly is the only way
to go.  C++ gives more scope for distancing between the source and the
object code, but does not change the principles.


David


On 12/04/2021 02:30, Trampas Stern wrote:
>  David, 
> 
> On the real cost of C++ I do not see the problems with debugging you
> do.  That is when I debug code I turn optimizations off, as such I can
> debug C++ just like C.  Now with compiler optimizations on all bets are
> off as to what the compiler does.  At this point you have to have near
> complete trust the compiler is doing the right thing.   
> 
> If you do not trust the compiler to do the right thing, you are using
> the wrong compiler.  
> 
> Trampas
> 
> On Sun, Apr 11, 2021 at 8:10 AM David Brown  > wrote:
> 
> Well, if you want a flame war, then let me chime in - you are wrong,
> Trampas is right.
> 
> You are /wrong/ to suggest that "commercial embedded systems ALWAYS
> directly benefit from being small and fast".  Some do - for many, it is
> irrelevant as long as they are small enough and fast enough.  Once you
> have reached the point of "good enough", anything more can often be
> simply a waste of money and development time.
> 
> Smaller code might mean you can use a cheaper microcontroller.  Unless
> you are nearing that point, however, making code smaller rarely helps.
> Faster code might mean you can use a cheaper device, or slower speed
> (lower EMI), or be in sleep mode more (lower power).  Sometimes these
> are important.  Faster development (of the same quality code), however,
> /always/ means cheaper engineering cost and if you get a faster time to
> market, then for some products that means big commercial benefits.
> 
> With that out of the way, the question is then whether C++ gives you
> bigger or smaller code, faster or slower code, greater or lower
> development costs in comparison to C.
> 
> And the answer there is - it depends.
> 
> If you don't know much about C++, using it is not going to be a benefit.
>  So that eliminates anyone who equates C++ and object-oriented coding.
> If you are using an older or weaker C++ tool, it is likely to have a lot
> of overhead.  If you are using an older C++ standard (C++03 or before),
> you lose out on many of the quality benefits of the language (just as
> you do if you use C90 rather than C99 or C11).  If you don't know how to
> use your tools well, such as disabling RTTI and exceptions and using
> optimisations, you will have a lot of overhead.  (That applies to C
> coding too, though marginally less so.)
> 
> So lets assume you know what you are doing, as Trampas seems to.  Start
> with the obvious stuff - 

Re: static class member as interrupt handler works, but not if class is templated

2021-04-11 Thread Anton Staaf
I also find it very helpful to extensively unit test my embedded code on
the host machine.  Even sensor handling code can often be tested by writing
signedness tests (given a change in input value what is the expected sign
of the change of the output).

-Anton

On Sun, Apr 11, 2021 at 5:32 PM Trampas Stern  wrote:

>  David,
>
> On the real cost of C++ I do not see the problems with debugging you do.
> That is when I debug code I turn optimizations off, as such I can debug C++
> just like C.  Now with compiler optimizations on all bets are off as to
> what the compiler does.  At this point you have to have near complete trust
> the compiler is doing the right thing.
>
> If you do not trust the compiler to do the right thing, you are using the
> wrong compiler.
>
> Trampas
>
> On Sun, Apr 11, 2021 at 8:10 AM David Brown 
> wrote:
>
>> Well, if you want a flame war, then let me chime in - you are wrong,
>> Trampas is right.
>>
>> You are /wrong/ to suggest that "commercial embedded systems ALWAYS
>> directly benefit from being small and fast".  Some do - for many, it is
>> irrelevant as long as they are small enough and fast enough.  Once you
>> have reached the point of "good enough", anything more can often be
>> simply a waste of money and development time.
>>
>> Smaller code might mean you can use a cheaper microcontroller.  Unless
>> you are nearing that point, however, making code smaller rarely helps.
>> Faster code might mean you can use a cheaper device, or slower speed
>> (lower EMI), or be in sleep mode more (lower power).  Sometimes these
>> are important.  Faster development (of the same quality code), however,
>> /always/ means cheaper engineering cost and if you get a faster time to
>> market, then for some products that means big commercial benefits.
>>
>> With that out of the way, the question is then whether C++ gives you
>> bigger or smaller code, faster or slower code, greater or lower
>> development costs in comparison to C.
>>
>> And the answer there is - it depends.
>>
>> If you don't know much about C++, using it is not going to be a benefit.
>>  So that eliminates anyone who equates C++ and object-oriented coding.
>> If you are using an older or weaker C++ tool, it is likely to have a lot
>> of overhead.  If you are using an older C++ standard (C++03 or before),
>> you lose out on many of the quality benefits of the language (just as
>> you do if you use C90 rather than C99 or C11).  If you don't know how to
>> use your tools well, such as disabling RTTI and exceptions and using
>> optimisations, you will have a lot of overhead.  (That applies to C
>> coding too, though marginally less so.)
>>
>> So lets assume you know what you are doing, as Trampas seems to.  Start
>> with the obvious stuff - writing C code and compiling it with a C++
>> compiler (with RTTI and exceptions disabled).  What are the overheads
>> and costs?  Nothing.  Zero.
>>
>> Add in namespaces, strong enumerations, proper constants instead of
>> #define's, inline functions instead of macros.  What are the overheads?
>>  Zero.  What are the benefits (in the hands of a good programmer)?
>> Clearer code, more chance of errors being caught by the compiler rather
>> than during testing (or after delivery to the customer).
>>
>> What about classes?  What are the costs when you are not using virtual
>> functions, multiple inheritance, etc.?  Nothing.  What about when you
>> /are/ using virtual functions and the like?  If you really need them
>> (usually you don't), then they can often be cheaper than equivalent code
>> in C using function pointers because the compiler can optimise them
>> better.  Use them unnecessarily, then of course there is a cost.
>>
>> What about templates?  The difference between template-generated code
>> and hand-written code is typically zero, but it can also give you
>> choices of a different balance between smaller object code or faster
>> object code (with more of the code being inlined).
>>
>> C++ gives more opportunities for misuse and bloat if you don't know how
>> to write C++ code for a small microcontroller.  But if you /do/ know, it
>> lets you write significantly better quality code that is likely to be
>> more efficient, not less.
>>
>> The real cost of C++, as I experience it, is for debugging.  You lose
>> the neat one-to-one relationship between functions in the source code
>> and functions in the object code that you used to get with old C
>> compilers.  With a good C compiler (like avr-gcc) you already lose a lot
>> of that as the compiler inlines code and moves things around.  But with
>> templated code, that effect is significantly amplified.
>>
>> David
>>
>>
>> On 11/04/2021 02:35, Bruce D. Lightner wrote:
>> > Trampas Stern,
>> >
>> > I'm sorry, but I've got to chime in here grasshopper.  David Kelly put
>> > it well: just "don't use C++"!
>> >
>> > I somehow knew that this would start a flame war. :-)
>> >
>> > [FLAME ON] We've been there, done that, bought the T-shirt, 

Re: static class member as interrupt handler works, but not if class is templated

2021-04-11 Thread Trampas Stern
 David,

On the real cost of C++ I do not see the problems with debugging you do.
That is when I debug code I turn optimizations off, as such I can debug C++
just like C.  Now with compiler optimizations on all bets are off as to
what the compiler does.  At this point you have to have near complete trust
the compiler is doing the right thing.

If you do not trust the compiler to do the right thing, you are using the
wrong compiler.

Trampas

On Sun, Apr 11, 2021 at 8:10 AM David Brown 
wrote:

> Well, if you want a flame war, then let me chime in - you are wrong,
> Trampas is right.
>
> You are /wrong/ to suggest that "commercial embedded systems ALWAYS
> directly benefit from being small and fast".  Some do - for many, it is
> irrelevant as long as they are small enough and fast enough.  Once you
> have reached the point of "good enough", anything more can often be
> simply a waste of money and development time.
>
> Smaller code might mean you can use a cheaper microcontroller.  Unless
> you are nearing that point, however, making code smaller rarely helps.
> Faster code might mean you can use a cheaper device, or slower speed
> (lower EMI), or be in sleep mode more (lower power).  Sometimes these
> are important.  Faster development (of the same quality code), however,
> /always/ means cheaper engineering cost and if you get a faster time to
> market, then for some products that means big commercial benefits.
>
> With that out of the way, the question is then whether C++ gives you
> bigger or smaller code, faster or slower code, greater or lower
> development costs in comparison to C.
>
> And the answer there is - it depends.
>
> If you don't know much about C++, using it is not going to be a benefit.
>  So that eliminates anyone who equates C++ and object-oriented coding.
> If you are using an older or weaker C++ tool, it is likely to have a lot
> of overhead.  If you are using an older C++ standard (C++03 or before),
> you lose out on many of the quality benefits of the language (just as
> you do if you use C90 rather than C99 or C11).  If you don't know how to
> use your tools well, such as disabling RTTI and exceptions and using
> optimisations, you will have a lot of overhead.  (That applies to C
> coding too, though marginally less so.)
>
> So lets assume you know what you are doing, as Trampas seems to.  Start
> with the obvious stuff - writing C code and compiling it with a C++
> compiler (with RTTI and exceptions disabled).  What are the overheads
> and costs?  Nothing.  Zero.
>
> Add in namespaces, strong enumerations, proper constants instead of
> #define's, inline functions instead of macros.  What are the overheads?
>  Zero.  What are the benefits (in the hands of a good programmer)?
> Clearer code, more chance of errors being caught by the compiler rather
> than during testing (or after delivery to the customer).
>
> What about classes?  What are the costs when you are not using virtual
> functions, multiple inheritance, etc.?  Nothing.  What about when you
> /are/ using virtual functions and the like?  If you really need them
> (usually you don't), then they can often be cheaper than equivalent code
> in C using function pointers because the compiler can optimise them
> better.  Use them unnecessarily, then of course there is a cost.
>
> What about templates?  The difference between template-generated code
> and hand-written code is typically zero, but it can also give you
> choices of a different balance between smaller object code or faster
> object code (with more of the code being inlined).
>
> C++ gives more opportunities for misuse and bloat if you don't know how
> to write C++ code for a small microcontroller.  But if you /do/ know, it
> lets you write significantly better quality code that is likely to be
> more efficient, not less.
>
> The real cost of C++, as I experience it, is for debugging.  You lose
> the neat one-to-one relationship between functions in the source code
> and functions in the object code that you used to get with old C
> compilers.  With a good C compiler (like avr-gcc) you already lose a lot
> of that as the compiler inlines code and moves things around.  But with
> templated code, that effect is significantly amplified.
>
> David
>
>
> On 11/04/2021 02:35, Bruce D. Lightner wrote:
> > Trampas Stern,
> >
> > I'm sorry, but I've got to chime in here grasshopper.  David Kelly put
> > it well: just "don't use C++"!
> >
> > I somehow knew that this would start a flame war. :-)
> >
> > [FLAME ON] We've been there, done that, bought the T-shirt, here in
> > forums like this before, going back many decades!  I've heard all your
> > silly platitudes repeatedly here and in other places---always coming
> > from "wise fools" like yourself.
> >
> > IMNSHO putting your specious arguments "on the Internet" for all
> > posterity to see is not the best move professionally.  When I see
> > statements like yours:
> >
> > /"Note that I have worked on projects in the past 

Re: static class member as interrupt handler works, but not if class is templated

2021-04-11 Thread Trampas Stern
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 
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:
> >
> > 007e ::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.)
>
>


Re: static class member as interrupt handler works, but not if class is templated

2021-04-11 Thread David Brown
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:
> 
> 007e ::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.)



Re: static class member as interrupt handler works, but not if class is templated

2021-04-11 Thread Trampas Stern
 "The man who grasps principles can successfully handle his own methods.
The man who tries methods, ignoring principles, is sure to have trouble."
-Ralph Waldo Emerson

When you understand your requirements, processor, and tools (compiler) then
you can pick the best method to optimize for desired results.
Blanket statements like "Don't use C++"  or that is "Slow and lots of
bloat." might be true based on how you would use the tools.


I agree C is a great programming language, it does has problems and every
year I learn new things I did not know in C. I also learned C++ and was in
the camp of no embedded C++ ever.  Then I did some testing and read more,
for example:
https://www.embedded.com/modern-c-in-embedded-systems-part-1-myth-and-reality/
https://bitvolatile.com/?p=326

I found that C++ was not evil if you knew how to use it.  So I started
doing some tests and found that in many cases the higher level abstraction
was worth it on larger projects. Plus I learned what was free in C++ and
what caused bloat and slowness.

For example here is the lines of code count for one of my last embedded
projects:
---
Languagefiles  blankcomment   code
---
C/C++ Header246  2065133660 89579
C++ 51   3977   3362
 36695
C 20   3545   6605
 12705
DOS Batch   1  0  0
  2
---
SUM:   318  28173   43627   138981
---

The code is large enough where the abstraction that C++ provides helps us
manage the project better.  This may have resulting performance and code
size hits on the processor, but it is worth it for the benefits.

Trampas

On Sat, Apr 10, 2021 at 11:40 PM Anton Staaf  wrote:

> For those that care, and ignoring the flame war, I believe that your
> (Klaus) problem likely stems from the following GCC bug:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435
>
> Sadly, support for C++ in AVR GCC is not a priority, so I wouldn't expect
> it to be fixed.  I've been able to work around this myself using explicit
> template instantiation, because I'm relying on a slightly different
> attribute that isn't propgated correctly.  I'm tagging an object as living
> in the .vectors section, and making its memory layout match the vector
> table layout for AVR processors.  This lets me generate only the vectors
> that are required using template meta programming based on the interrupts
> that are listened for.  I've built my avr-gcc with "--with-avrlibc=no" and
> "--without-newlib" to suppress the misspelled ISR warning.
>
> -Anton
>
> On Sat, Apr 10, 2021 at 8:19 PM Russell Shaw 
> wrote:
>
>> On 11/4/21 8:36 am, Trampas Stern wrote:
>> > Actually C++ is not slower or more bloat than C, depending on the
>> features used.
>> >
>> > For example I do not use RTTI or exceptions, so that makes it about the
>> same as
>> > C for size. Yes you have to turn these features off in your compiler
>> (-fno-rtti,
>> > -fno-exceptions).  Sure you have trampolines or jump tables for
>> function
>> > overloading but you have to do the same in C. If you do not use
>> inheritance or
>> > function overloading you do not have the penalty.
>>
>> Function overloading is a compile-time concept, but the result after name
>> scope
>> flattening are simple function names that are called without any extra
>> pointer
>> indirections (ie, no different than C).
>>
>> C++ is as efficient as C only if what is written translates to the
>> equivalent
>> form. This is easy to do, but only after a large hurdle of understanding
>> how C++
>> compilers work.
>>
>> The biggest shortcoming in the C++ "industry" is that there is no
>> literature i
>> have seen that explains in a compact way how you can look at a piece of
>> C++ code
>> and see how it would translate to the equivalent assembly, which is the
>> main
>> advantage of C.
>>
>>


Re: static class member as interrupt handler works, but not if class is templated

2021-04-11 Thread David Brown
Well, if you want a flame war, then let me chime in - you are wrong,
Trampas is right.

You are /wrong/ to suggest that "commercial embedded systems ALWAYS
directly benefit from being small and fast".  Some do - for many, it is
irrelevant as long as they are small enough and fast enough.  Once you
have reached the point of "good enough", anything more can often be
simply a waste of money and development time.

Smaller code might mean you can use a cheaper microcontroller.  Unless
you are nearing that point, however, making code smaller rarely helps.
Faster code might mean you can use a cheaper device, or slower speed
(lower EMI), or be in sleep mode more (lower power).  Sometimes these
are important.  Faster development (of the same quality code), however,
/always/ means cheaper engineering cost and if you get a faster time to
market, then for some products that means big commercial benefits.

With that out of the way, the question is then whether C++ gives you
bigger or smaller code, faster or slower code, greater or lower
development costs in comparison to C.

And the answer there is - it depends.

If you don't know much about C++, using it is not going to be a benefit.
 So that eliminates anyone who equates C++ and object-oriented coding.
If you are using an older or weaker C++ tool, it is likely to have a lot
of overhead.  If you are using an older C++ standard (C++03 or before),
you lose out on many of the quality benefits of the language (just as
you do if you use C90 rather than C99 or C11).  If you don't know how to
use your tools well, such as disabling RTTI and exceptions and using
optimisations, you will have a lot of overhead.  (That applies to C
coding too, though marginally less so.)

So lets assume you know what you are doing, as Trampas seems to.  Start
with the obvious stuff - writing C code and compiling it with a C++
compiler (with RTTI and exceptions disabled).  What are the overheads
and costs?  Nothing.  Zero.

Add in namespaces, strong enumerations, proper constants instead of
#define's, inline functions instead of macros.  What are the overheads?
 Zero.  What are the benefits (in the hands of a good programmer)?
Clearer code, more chance of errors being caught by the compiler rather
than during testing (or after delivery to the customer).

What about classes?  What are the costs when you are not using virtual
functions, multiple inheritance, etc.?  Nothing.  What about when you
/are/ using virtual functions and the like?  If you really need them
(usually you don't), then they can often be cheaper than equivalent code
in C using function pointers because the compiler can optimise them
better.  Use them unnecessarily, then of course there is a cost.

What about templates?  The difference between template-generated code
and hand-written code is typically zero, but it can also give you
choices of a different balance between smaller object code or faster
object code (with more of the code being inlined).

C++ gives more opportunities for misuse and bloat if you don't know how
to write C++ code for a small microcontroller.  But if you /do/ know, it
lets you write significantly better quality code that is likely to be
more efficient, not less.

The real cost of C++, as I experience it, is for debugging.  You lose
the neat one-to-one relationship between functions in the source code
and functions in the object code that you used to get with old C
compilers.  With a good C compiler (like avr-gcc) you already lose a lot
of that as the compiler inlines code and moves things around.  But with
templated code, that effect is significantly amplified.

David


On 11/04/2021 02:35, Bruce D. Lightner wrote:
> Trampas Stern,
> 
> I'm sorry, but I've got to chime in here grasshopper.  David Kelly put
> it well: just "don't use C++"!
> 
> I somehow knew that this would start a flame war. :-)
> 
> [FLAME ON] We've been there, done that, bought the T-shirt, here in
> forums like this before, going back many decades!  I've heard all your
> silly platitudes repeatedly here and in other places---always coming
> from "wise fools" like yourself.
> 
> IMNSHO putting your specious arguments "on the Internet" for all
> posterity to see is not the best move professionally.  When I see
> statements like yours:
> 
> /"Note that I have worked on projects in the past where we squeezed
> every clock and every byte out of a processor. However I have not had to
> optimize for size or speed in 10 years.  That is processors are so cheap
> and powerful if you have to optimize code for size or speed then you
> most likely picked the wrong microprocessor."
> /
> 
> ...you are definitely NOT ever going to be working with me.
> 
> Why is plain old C still one of the most popular programming
> languages---number 1 by some measures (i.e.,
> https://tiobe.com/tiobe-index/)?  It's because commercial embedded
> systems ALWAYS directly benefit from small and fast.  If you are a
> hobbyist you can make statements like you did.  

Re: static class member as interrupt handler works, but not if class is templated

2021-04-10 Thread Anton Staaf
For those that care, and ignoring the flame war, I believe that your
(Klaus) problem likely stems from the following GCC bug:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435

Sadly, support for C++ in AVR GCC is not a priority, so I wouldn't expect
it to be fixed.  I've been able to work around this myself using explicit
template instantiation, because I'm relying on a slightly different
attribute that isn't propgated correctly.  I'm tagging an object as living
in the .vectors section, and making its memory layout match the vector
table layout for AVR processors.  This lets me generate only the vectors
that are required using template meta programming based on the interrupts
that are listened for.  I've built my avr-gcc with "--with-avrlibc=no" and
"--without-newlib" to suppress the misspelled ISR warning.

-Anton

On Sat, Apr 10, 2021 at 8:19 PM Russell Shaw  wrote:

> On 11/4/21 8:36 am, Trampas Stern wrote:
> > Actually C++ is not slower or more bloat than C, depending on the
> features used.
> >
> > For example I do not use RTTI or exceptions, so that makes it about the
> same as
> > C for size. Yes you have to turn these features off in your compiler
> (-fno-rtti,
> > -fno-exceptions).  Sure you have trampolines or jump tables for function
> > overloading but you have to do the same in C. If you do not use
> inheritance or
> > function overloading you do not have the penalty.
>
> Function overloading is a compile-time concept, but the result after name
> scope
> flattening are simple function names that are called without any extra
> pointer
> indirections (ie, no different than C).
>
> C++ is as efficient as C only if what is written translates to the
> equivalent
> form. This is easy to do, but only after a large hurdle of understanding
> how C++
> compilers work.
>
> The biggest shortcoming in the C++ "industry" is that there is no
> literature i
> have seen that explains in a compact way how you can look at a piece of
> C++ code
> and see how it would translate to the equivalent assembly, which is the
> main
> advantage of C.
>
>


Re: static class member as interrupt handler works, but not if class is templated

2021-04-10 Thread Russell Shaw

On 11/4/21 8:36 am, Trampas Stern wrote:

Actually C++ is not slower or more bloat than C, depending on the features used.

For example I do not use RTTI or exceptions, so that makes it about the same as 
C for size. Yes you have to turn these features off in your compiler (-fno-rtti, 
-fno-exceptions).  Sure you have trampolines or jump tables for function 
overloading but you have to do the same in C. If you do not use inheritance or 
function overloading you do not have the penalty.


Function overloading is a compile-time concept, but the result after name scope 
flattening are simple function names that are called without any extra pointer 
indirections (ie, no different than C).


C++ is as efficient as C only if what is written translates to the equivalent 
form. This is easy to do, but only after a large hurdle of understanding how C++ 
compilers work.


The biggest shortcoming in the C++ "industry" is that there is no literature i 
have seen that explains in a compact way how you can look at a piece of C++ code 
and see how it would translate to the equivalent assembly, which is the main 
advantage of C.




Re: static class member as interrupt handler works, but not if class is templated

2021-04-10 Thread Bruce D. Lightner

Trampas Stern,

I'm sorry, but I've got to chime in here grasshopper.  David Kelly put 
it well: just "don't use C++"!


I somehow knew that this would start a flame war. :-)

[FLAME ON] We've been there, done that, bought the T-shirt, here in 
forums like this before, going back many decades!  I've heard all your 
silly platitudes repeatedly here and in other places---always coming 
from "wise fools" like yourself.


IMNSHO putting your specious arguments "on the Internet" for all 
posterity to see is not the best move professionally.  When I see 
statements like yours:


/"Note that I have worked on projects in the past where we squeezed 
every clock and every byte out of a processor. However I have not had to 
optimize for size or speed in 10 years.  That is processors are so cheap 
and powerful if you have to optimize code for size or speed then you 
most likely picked the wrong microprocessor."

/

...you are definitely NOT ever going to be working with me.

Why is plain old C still one of the most popular programming 
languages---number 1 by some measures (i.e., 
https://tiobe.com/tiobe-index/)?  It's because commercial embedded 
systems ALWAYS directly benefit from small and fast. If you are a 
hobbyist you can make statements like you did. However us professional C 
programmers that get paid the "big bucks" are in demand precisely 
because they can deliver products that run with minimal compute 
resources on the least expensive microcontrollers possible!


And, yes one can reuse C code---I've been doing it for decades. As for 
interrupt handlers and device drivers, between C macros and 
programmatically generated C code (e.g., Perl scripts) you can have it 
all without the "crutch" of C++ templates and class nonsense. [FLAME OFF!]


BTW: I suggest that you quit while you're ahead---but David and I 
somehow know that you won't! :-)


Best regards,

Bruce D. Lightner
Lightner Engineering
La Jolla, California
light...@lightner.net
https://www.linkedin.com/in/brucedlightner/


On 4/10/2021 3:36 PM, Trampas Stern wrote:
Actually C++ is not slower or more bloat than C, depending on the 
features used.


For example I do not use RTTI or exceptions, so that makes it about 
the same as C for size. Yes you have to turn these features off in 
your compiler (-fno-rtti, -fno-exceptions). Sure you have 
trampolines or jump tables for function overloading but you have to do 
the same in C. If you do not use inheritance or function 
overloading you do not have the penalty.


I find that in most of my embedded projects the cost of development 
time is more than the cost of the processor for 5 years of production, 
that is the products are not super high volume products.  As such, 
reducing development time is very important.   To this end I do things 
like write libraries and test them, and then reuse them.  For example 
I write an abstract interface class for a CharDevice, and BlockDevice. 
Then a UART can be a CharDevice and EEPROM a BlockDevice, SDCard is a 
BlockDevice, etc.  This allows faster development.  Sure I can do this 
in C, but C++ basically does the same thing I would do in C and is 
easier to understand.


Also things like templates are valuable, for example I wrote a FIFO 
template.  I debug that template once and never have to write fifo 
code again.  This is something very hard to do in C with any 
efficiency.  Now I can create a FIFO for uint8_t, uint32_t, or a 
structure with one line.  This can not be done easy in C. The same is 
true for circular buffers and such...


So yea C++ on embedded is very valid and real.   I have been doing 
professional embedded C for over 30 years and just switched to C++ and 
do not want to go back to C.  The misconceptions about bloat are no 
longer valid.  Sure you can write bad C++ code using standard 
templates and such but you can also write bad C code, so don't do 
either. I think the misconception about C++ is because people try to 
do stupid stuff like use cout, new, RTTI, exceptions, etc.  Where most 
of the time the simple compile time features of C++ offer huge 
advantages over C.


At the end of the day all the compile time features of C++ are 
free, like classes. There is zero reason not to use them because they 
are free. The run time features are not free but you can choose what 
you use, and turn off what you don't need.


So yes I can write bad C++ code that is slow and bloated. I can write 
bad C code that is slow and bloated. My job is to write functional 
code that works and works correctly with no side effects and I can do 
that faster and more efficiently in C++ using OO and minimal features 
of C++.  Maybe others can not, but that is not my problem.


Note that I have worked on projects in the past where we squeezed 
every clock and every byte out of a processor. However I have not had 
to optimize for size or speed in 10 years.  That is processors are so 
cheap and 

Re: static class member as interrupt handler works, but not if class is templated

2021-04-10 Thread Trampas Stern
Actually C++ is not slower or more bloat than C, depending on the features
used.

For example I do not use RTTI or exceptions, so that makes it about the
same as C for size. Yes you have to turn these features off in your
compiler (-fno-rtti, -fno-exceptions).  Sure you have trampolines or jump
tables for function overloading but you have to do the same in C. If you do
not use inheritance or function overloading you do not have the penalty.

I find that in most of my embedded projects the cost of development time is
more than the cost of the processor for 5 years of production, that is the
products are not super high volume products.  As such, reducing development
time is very important.   To this end I do things like write libraries and
test them, and then reuse them.  For example I write an abstract interface
class for a CharDevice, and BlockDevice.  Then a UART can be a CharDevice
and EEPROM a BlockDevice, SDCard is a BlockDevice, etc.  This allows faster
development.  Sure I can do this in C, but C++ basically does the same
thing I would do in C and is easier to understand.

Also things like templates are valuable, for example I wrote a FIFO
template.  I debug that template once and never have to write fifo code
again.  This is something very hard to do in C with any efficiency.  Now I
can create a FIFO for uint8_t, uint32_t, or a structure with one line.
This can not be done easy in C. The same is true for circular buffers and
such...

So yea C++ on embedded is very valid and real.   I have been doing
professional embedded C for over 30 years and just switched to C++ and do
not want to go back to C.  The misconceptions about bloat are no longer
valid.  Sure you can write bad C++ code using standard templates and such
but you can also write bad C code, so don't do either. I think the
misconception about C++ is because people try to do stupid stuff like use
cout, new, RTTI, exceptions, etc.  Where most of the time the simple
compile time features of C++ offer huge advantages over C.

At the end of the day all the compile time features of C++ are free, like
classes. There is zero reason not to use them because they are free. The
run time features are not free but you can choose what you use, and turn
off what you don't need.

So yes I can write bad C++ code that is slow and bloated. I can write bad C
code that is slow and bloated. My job is to write functional code that
works and works correctly with no side effects and I can do that faster and
more efficiently in C++ using OO and minimal features of C++.  Maybe others
can not, but that is not my problem.

Note that I have worked on projects in the past where we squeezed every
clock and every byte out of a processor. However I have not had to optimize
for size or speed in 10 years.  That is processors are so cheap and
powerful if you have to optimize code for size or speed then you most
likely picked the wrong microprocessor.

The problem with interrupt handlers which I asked about still exists if you
use C to write the code.  That is you still have to map the interrupt
handler to the correct instance of the object unless you are insane and
write a driver for each UART instance, which talking about bloat and
slow

Trampas





On Sat, Apr 10, 2021 at 5:12 PM David Kelly  wrote:

> On Apr 10, 2021, at 2:37 PM, Trampas Stern  wrote:
>
> If you guys have a better way I would love to know.
>
>
> Don’t use C++?
>
> What does object-oriented coding do for embedded projects? It’s akin to
> using printf(). Slow and lots of bloat.
>
> Time once was I put uint32 in a union so as to code ++ inline rather than
> let avr-gcc call a library routine. Even more so if in an interrupt. Not
> all library routines used to be re-entrant.
>
> --
> David Kelly N4HHE, dke...@hiwaay.net 
> 
> Whom computers would destroy, they must first drive mad.
>
>


Re: static class member as interrupt handler works, but not if class is templated

2021-04-10 Thread David Kelly
On Apr 10, 2021, at 2:37 PM, Trampas Stern  wrote:

> If you guys have a better way I would love to know. 

Don’t use C++?

What does object-oriented coding do for embedded projects? It’s akin to using 
printf(). Slow and lots of bloat.

Time once was I put uint32 in a union so as to code ++ inline rather than let 
avr-gcc call a library routine. Even more so if in an interrupt. Not all 
library routines used to be re-entrant.

--
David Kelly N4HHE, dke...@hiwaay.net

Whom computers would destroy, they must first drive mad.


Re: static class member as interrupt handler works, but not if class is templated

2021-04-10 Thread Klaus

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:

007e ::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




Re: static class member as interrupt handler works, but not if class is templated

2021-04-10 Thread Trampas Stern
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 
wrote:

>
>
> On Sat, 10 Apr 2021, 15:07 Klaus Rudolph via Gcc-help, <
> gcc-h...@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::Handler()
>> {
>>
>> }
>>
>> Dummy<1> d1;
>>
>
> This doesn't cause the instantiation of the member function.
>
> Have you tried an explicit instantiation?
>
> template class Dummy<1>;
>
>
>
>


Re: static class member as interrupt handler works, but not if class is templated

2021-04-10 Thread Jonathan Wakely
On Sat, 10 Apr 2021, 15:07 Klaus Rudolph via Gcc-help, 
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::Handler()
> {
>
> }
>
> Dummy<1> d1;
>

This doesn't cause the instantiation of the member function.

Have you tried an explicit instantiation?

template class Dummy<1>;