C++ syntax without C++

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Hi,

What, specifically, can I use of C++'s syntax without incurring the
associated "costs" that C++ brings with it?  I'm ideally looking for
criteria that I could *mechanically* enforce (a preprocessor to scan
for "features" that are "beyond C" in cost/complexity and flag them
for excisement).

Of course, this bends the issue of "implementation defined" in
some cases -- I'll worry about specific toolchains, later.

E.g., using "//" comments should have no impact on the code
generated.

I *suspect* I should be able to use namespaces and similarly not
changed the code perceptibly -- beyond what simply prepending the
namespace's identifier to all identifiers *IN* that namespace?

The exception syntax is particularly appealing.  But, I suspect
that implementations can vary a lot and bring other cruft into
the equation once I start down that path.

What else is "free"?  Safe?

I.e., disallowing the "class" keyword probably goes a long way
to keeping cruft out of the binary... are there other insidious
things that can drag cruft back *in*??  (e.g., startup code)

Thx,
--don

Re: C++ syntax without C++
On Tue, 05 Nov 2013 17:10:18 -0700, Don Y wrote:

Quoted text here. Click to load it

There's probably articles and books on this.

C++ can be fairly slim and trim, if you're careful.

* Using classes and inheritance doesn't drag in much cruft.
* Using virtual functions drags in a teeny bit of cruft (each new type --  
type, not object -- has a virtual function table)
* Using exceptions drags in cruft, the kitchen sink, the world, and  
various planets
* Using "new" drags in malloc, free, heap management, exception handling,  
etc.

If you get into the habit of looking at your map file, you can watch it  
grow as you add things, and get an idea of what's getting sucked in.

--  
Tim Wescott
Control system and signal processing consulting
We've slightly trimmed the long signature. Click to see the full one.
Re: C++ syntax without C++
Hi Tim,

On 11/5/2013 10:15 PM, Tim Wescott wrote:
Quoted text here. Click to load it



Sorry, I'm not thinking in terms of some big library, RTTI, etc.
that gets dragged in when I use "feature X".  Rather, all the stuff
that happens "in the whitespace" between statements, operators, etc.

E.g., anonymous objects, constructors/destructors, etc.

In C, I can look at the code and tell you with reasonable confidence
how much is happening (cost) in a given statement.  With C++, you
have to *know* the cost of each constructor/destructor, dependant
classes that get dragged in, overloaded operators, etc.  The syntax
hides a lot of "mechanism".

E.g., in Limbo, I can write
    greeting := "Hello"
    greeting += ", World!"
and have no *real* clue as to what the actual cost is (in time or space)
(i.e., does the initial declaration allocate extra space above and
beyond len("Hello")?  If so, does it allocate enough to append the
", World!"?  Or, must another allocation and copy take place??  Will
the GC be invoked *now* -- or *later*??)

By contrast, C's syntax maps semi-"transparently" onto the underlying
hardware.  (perhaps the biggest issue being the presence of any
"helper routines" to implement types not directly supported in the
native hardware).

Returning to my question...

Use of // comments should cost nothing!  <d'uh>

Use of namespaces should *also* cost nothing (i.e., you should be
able to handle namespaces in the preprocessor, effectively).

Once you type "class" then you start dragging in extra scaffolding
to support classes.  I.e., auto variables aren't just indexes into
the stack frame ALLOCATED EN MASSE at function invocation.  Instead,
they are constructor instantiations (even if trivial).  Similarly,
terminating a function doesn't just elide the stack frame in which
the autos were created but, instead, implicitly invokes the destructors
for all of the objects that will now cease to exist.

[This is what I mean by stuff "in the whitespace" -- you never *see*
these invocations; you just have to remind yourself that they are
there and how much *each* costs]


Re: C++ syntax without C++
On 06/11/13 07:58, Don Y wrote:
Quoted text here. Click to load it

I think you should start by buying a book on C++ and learning /real/
C++.  Obviously you should concentrate on the sort of features you are
going to use in the end.  But your posts here show a serious lack of
knowledge and understanding of C++, as well as very limited ideas of
what compilers do and how they work.

Having said that, I will give the best answers I can.


The biggest step towards getting efficient (compact and fast) C++ code
is exactly the same as for C code.  Get a decent compiler, learn how to
use it, and in particular learn to use its optimisations appropriately.
 Compilers will generate big and ugly object code if the optimiser is
not enabled - this applies even more so to C++.  For C++, you also have
to learn how and when the compiler generates code from templates - done
right, you should not see any code duplication or unused code (you might
see it in assembly listings, but it should be removed or combined by the
linker).


Aim for C++11.  It has a number of improvements that make it easier to
write correct code, and avoid accidents ("explicit" conversion operators
and constructors, "enum class", better control of automatically
generated member functions, static assertions, etc.), as well as
convenient features like "auto", "const_expr" and lambdas.


Always be wary of library code.  (This applies to C as well as C++.)
Test things first to make sure you are not bringing in more than you
need.  But don't assume library code /always/ means big and inefficient.


The key "cost" in C++ is exceptions, followed by RTTI.  Any decent C++
compiler - especially for embedded systems - will let you disable these.
 Exceptions are very hard to use /well/ - you really have to think about
them throughout your program, and be aware that they can do unexpected
things at unexpected times if you are not careful.  They are basically
undocumented "gotos".  They can also lead to a lot of extra code space
(holding all the rules for handling exceptions at different places) and
sometimes also stack and data space, and they can severely limit
optimisations because the compiler no longer has a full picture of the
control flow.  So my advice is to disable them in the compiler - then
they cost nothing.

Quoted text here. Click to load it

Almost every feature of C++ is "free" - exceptions are the only feature
I know of that "costs".  For everything else, the cost depends on use
and misuse.  Sometimes these costs are hidden, at least at the time they
are used - but they are not /extra/ costs.

(It is worth emphasising again that you need to enable optimisation - it
is easy to write code that makes extra copies of temporary objects,
which will be eliminated by the optimiser but will give code bloat
without optimisation.)

For example, when you declare a new object of a class, its constructor
is called - you don't see it when you use the class, but you /do/ see it
when you define the class.  And the cost is pretty much the same as if
you used a plain C "struct" and called an "init" function on it.

(As noted above, C++11 has features to help avoid accidentally doing
more work than you intended.)

One point to consider here is inlining (either explicitly, or implicitly
by defining functions inside the class definition).  Inlining can lead
to significantly smaller code as it eliminates the call overhead and
gives more scope for optimisation (such as constant propagation, dead
code elimination and strength reduction).  But done badly, it can lead
to overall code increases due to duplication.


Quoted text here. Click to load it

It doesn't add /any/ cruft at all.  If you haven't used "virtual", then
a class (derived or not) takes the same data space as a C "struct", and
the member functions are identical to C functions taking a pointer to
the struct.  You only get "cruft" if you are accidentally calling extra
conversion operators, constructors, etc.  You avoid that by carefully
defining your classes, and using "explicit", "default", "deleted".

Quoted text here. Click to load it

Calling a virtual method is also slower than calling a non-virtual
method (though if the compiler can figure out the exact type at
compile-time, it can skip the virtual table lookup and call the method
directly).  But using virtual functions is typically more efficient than
alternative mechanisms such as function pointers or selector functions.
 So when you actually /need/ a virtual method, it is an efficient system.

(Many C++ programmers use "virtual" all over the place, "just in case".
 But we are talking about efficient embedded C++ programming here, not
the bad habits of desktop programmers!)

Quoted text here. Click to load it

They are not necessarily /that/ bad - I'd stop at the kitchen sink.

Quoted text here. Click to load it

"new" drags in heap management, just like "malloc" - but not exception
handling if it is disabled.  And like "malloc", you can write your own
memory handling if you want.  (For example, you could have a memory
handler that does not support free/delete, which is fine when you only
ever allocate memory at program startup and never need to free it
because your program never stops.  Such memory handlers are very small
and simple.)

Quoted text here. Click to load it

Absolutely!  (This applies to C programming as well.)

Quoted text here. Click to load it

Anonymous objects are usually eliminated, or at least minimised, by the
optimiser.  Before complaining about them, write some code where you can
see they are actually causing code bloat.  Then try and redo the code in
plain C - it is unlikely to be much smaller, and will certainly be more
complex.  Then ask yourself this - is it better with simple source code
that generates more object code than you expect, or is it better with
longer and more complex source code that generates about the same object
code?  If you prefer the more explicit and longer source code, then
that's fine - write that in C++.

Remember, apart from exceptions and RTTI, /nothing/ in C++ costs
/anything/ unless you use that feature.

If you don't like code from constructors, don't use them.  Default
constructors will zero out the members - but the compiler should
eliminate redundant stores (if the constructor is inline).  Default
destructors won't do anything at all.

There is very little (if any) cost to this, compared to the equivalent C
code of declaring a struct, manually initialising its members and/or
calling an "init" function.  What changes is /where/ you describe this
to the compiler, your fellow developers, and yourself.  With C++, you
state the initialisation requirements in the class definition, and the
compiler enforces them automatically when the class is used.  With C,
you state it in unenforceable documentation and comments in the headers,
and must write it explicitly each time you use the struct.

Quoted text here. Click to load it

That's true - as long as you never use any functions, or any features
not supported directly by the target (such as floating point on a small
micro).  In other words, that's a common misconception.

Quoted text here. Click to load it

It is certainly true that C++ has more such cases - every definition of
a class object can be thought of as a "function call".

Overloaded operators are no more and no less than function calls with a
different syntax.

So when you are writing code where efficiency is important, it is vital
that you know about the class types you are using.  But how is that
different from C programming, where you need to know about the functions
you are using?

Quoted text here. Click to load it

And how is that different from writing the roughly equivalent C code?

    char* greeting = (char*) malloc(6);
    strcpy(greeting, "Hello");
    greeting = (char*) realloc(greeting, 6 + 8);
    strcat(greeting, ", World!");

Do you know the /actual/ cost of malloc and realloc?  Either you know
exactly how these functions are defined in your particular toolchain, or
you guess.  Do you know the /actual/ cost of strcpy() and strcat()?
These can be defined in many different ways too.
    

Quoted text here. Click to load it

As shown above, that's a mixture of myth and misunderstanding - at best,
it only applies if you never call a function for which you haven't
studied the source code.  And exactly the same applies to C++ - the only
difference is that some of the "function calls" are less obvious when
they are used (though equally obvious where they are defined).

Quoted text here. Click to load it

Join the world of C99 - it's only 15 years old.

Quoted text here. Click to load it

Namespaces are not handled by the preprocessor, but you are correct that
they cost nothing.

Quoted text here. Click to load it

No, you don't.

Quoted text here. Click to load it

Neither are local variables in C.  The compiler does all sorts of stuff
with them, such as putting them in registers, re-using slots,
eliminating them entirely, changing their types or codings, allocating
and deallocating stack space at different points in the function, etc.

The compiler will do the same thing with C++ class objects.  Small class
objects will go in registers and be optimised just like small C
variables - and big ones will get manipulated in much the same way as C
structs.

Quoted text here. Click to load it

And where they are trivial enough, they will get eliminated by the
compiler if they are not needed.  If the constructor effects /are/
needed (after all, you do want to initialise your variables at /some/
point), then the constructor is just as efficient as C assignment for
initialisation.

Quoted text here. Click to load it

Only if the destructors have an effect - in which case you really do
want to run them!

Quoted text here. Click to load it

I am surprised that you are regurgitating the decades old anti-C++
propaganda, while missing the "big" points.


C++ is harder for syntax checking.  C++ compilers are generally very
good at spotting a compilation error, but very bad at telling you where
the error /really/ lies.  But they have got a lot better in recent years.

C++ is harder to debug, especially at the assembly level.  Name
mangling, inlined code, etc., makes it a lot harder to follow.

C++ toolchains are often expensive (sometimes ridiculously so compared
to C toolchains), and are often out of date.

C++ code is often (but not necessarily) pointer-heavy as member
functions effectively take a pointer to the object as their first
argument.  This is no different from a C function that has a pointer
parameter, but the style is more prevalent in C++ code.  This is costly
for small cpus that have poor pointer support (8051, AVR, etc.).


Then there are the two big "code bloat" features that you haven't
mentioned - inlining, and templates.

"inlining", as noted earlier, can be a win or a loss - sometimes
dramatically so.  Use it carefully, thinking about how the code will
/actually/ be used and what the resulting generated object code will
look like.  This applies equally to C99, of course.


Templates can be done badly and lead to a lot of code duplication.  But
they can also be done well, and lead to simpler source code and smaller
generated code.

For example, you might have a class that wraps a microcontroller's UARTs
to give nice functions like sendChar(), bufferReady(), etc., that map
directly onto accesses of the UART's registers.

You've got something like this from the normal C headers:

typedef struct {
    volatile uint16_t baud;
    volatile uint16_t control;
    volatile uint8_t status;
    volatile uint8_t data;
} UART_T;
#define STATUS_BUFFER_READY 0x02
...
#define UART0 (*(UART_T*)(0x10000))
#define UART1 (*(UART_T*)(0x10100))


In C, you define your general functions like this:

bool bufferReady(UART_T *pUart) {
    return (pUart->status) & STATUS_BUFFER_READY;
}

and you call it like this:

#define uartDebug UART0
#define uartPC UART1

if (bufferReady(uartDebug)) ...


This works nicely, and you've got a flexible API that supports multiple
uarts.


In C++ with a class, you have this:

class Uart {
private:
    UART_T *pUart;
public :
    Uart(UART_T *p) { pUart = p; }
    bool bufferReady(void) {
        return (pUart->status) & STATUS_BUFFER_READY;
}

and you use it like this:

Uart uartDebug(UART0);
Uart uartPC(UART1);

if (uartDebug.bufferReady()) ...

That's also fine, and the code size and speed will be virtually
identical to that of the C code.


With C++ templates, you can do this:

template <UART_T * P>
class Uart {
public:
    static bool bufferReady(void) {
        return (P->status) & STATUS_BUFFER_READY;
    }
}

and use it as

Uart<UART0> uartDebug;
Uart<UART1> uartPC;

if (uartDebug.bufferReady()) ...


In use, the templated code is as clear and easy as the C++ and C code.
But there is a huge difference in the generated code - with the
templates, the compiler knows exactly which addresses you are talking
about - there is no longer any function call, and the complier can test
the single bit directly without any pointers.



Re: C++ syntax without C++
On 11/6/2013 2:19 AM, David Brown wrote:
Quoted text here. Click to load it

David, your posts are always "you don't know what you're doing/saying
/asking".  Yet, you know absolutely NOTHING about me, my credentials,
my accomplishments, goals, etc.  And, from *my* experiences with you,
apparently nothing about the things you so quickly mouth off about.

Go fuck yourself.



Re: C++ syntax without C++
On 06/11/13 10:33, Don Y wrote:
Quoted text here. Click to load it

Well, that was a surprise!

You are, of course, completely wrong about what I know about you - you
post a great deal, and thus everyone who reads c.a.e. knows at least
something of your experiences and knowledge.  You can't tell us so much
over the years, and both give advice and ask for advice, without leaving
some impressions.

I don't know if you mean that /all/ my posts in c.a.e. are "you don't
know what you are doing/saying/asking", or referring to all my replies
to /your/ posts, or just to this post and another recent one on
capabilities.  But as a general rule, if I feel that someone is mixed up
or unclear in what they are saying, then I think it is reasonable to ask
them if they have thought through things properly.  When someone is
having difficultly figuring out the details and consequences of a
complex solution, the first thing to do is go back a step and try to
understand the guts of the problem, and then ask if there is not a
simpler solution.  (And I know I don't need to tell you this - I am
telling you that this is what I was doing regarding the capabilities
posts.  And you'll note that I dropped out of that thread when it was
clear that you /had/ determined that the complex solution was necessary.)

I stand by impression that your C++ knowledge and experience is limited
- or why you would be asking the questions about the supposed overheads
on basic C++ features if you were familiar with them already?

But on re-reading my post, I can see I was unnecessarily sarcastic,
impolite or patronising at points, and for that I apologise.  My
intention was to help you and correct misconceptions - my post would
have been better with some parts omitted or completely re-worded.  It is
a shame that you have got hung up on those sections.

If you want to discuss the rest of the post, snipping those bits, then
that would be fine - we can see if we agree or disagree on the technical
parts.





Re: C++ syntax without C++

Quoted text here. Click to load it

I thought it an excellent post, in fact it inspires me - for the first
time - to try c++ myself for embedded.

Most times I see c++ mentioned here it is with distain, it is nice to
see another point of view.

Quoted text here. Click to load it

He has always been spot-on AFAICT. Certainly in the areas I do know
something about.

Quoted text here. Click to load it

Totally uncalled for Don.


--  

John Devereux

Re: C++ syntax without C++
On 11/06/13 12:31, John Devereux wrote:

Quoted text here. Click to load it

Same here John. I found it very informative and must have taken quite a bit
of time to prepare. I read it from end to end.

There's too much of this sort of thing nowadays - sensitive egos looking to
find fault where there is none and completely ignoring the generosity of
others. Sad really...

Chris


--  
Embedded Systems Hardware & Software Engineering
Oxford England
We've slightly trimmed the long signature. Click to see the full one.
Re: C++ syntax without C++
On 06/11/13 09:19, David Brown wrote:
Quoted text here. Click to load it

I presume by that you mean a subset of C++. Probably a
different subset to many other people, which brings
severe problems when you want to expand your team or
enter maintenance mode.

Quoted text here. Click to load it

C++ optimisation brings different problems: programs start
behaving subtly incorrectly because the programmer didn't
understand the particular interpretation of C++ semantics
that had been chosen by the compiler implementer.

Don't take my word for it. Do listen to those that have far
more experience of these problems at the sharp end.
For mere starters, I refer you to comp.arch and comp.std.c++


Quoted text here. Click to load it

And there has been at least one C++ compiler
for 2/3 of that time :( (As opposed to a myriad
of compilers which support different subsets of
C++)

Is there a *complete* C++11 compiler yet?
One that the vast majority of people regard
as complete?


Quoted text here. Click to load it

I think you are missing different "big points".




Re: C++ syntax without C++
On 06/11/13 11:05, Tom Gardner wrote:
Quoted text here. Click to load it

What I mean is that you have to try writing, compiling, and analysing
C++ code of the sort you want to use, using the sorts of tools you want
to use.  If you want to know exactly what sort of code is generated for
different types of source code, you have to try it out - you don't guess
based on ideas about the "inefficiencies of C++" that you have heard
somewhere.

Quoted text here. Click to load it

There are good reasons for not going overboard with enabling the most
enthusiastic optimisations, as they can make debugging far more
difficult.  But both C and C++ are very inefficient if the compiler is
not allowed to do its job - though the effect will normally be worse for
C++.

You have to understand the language you are using - there is no way
around that.  You also have to understand your tools, and let them help
you - full use of your compilers warnings and checks (and possibly help
from additional tools like pc-lint) will catch a number of errors early.

But if you think you can disable optimisations and write "looser" code
with missing "volatile", alias issues, signed overflows, etc., just
because it "works fine" without optimisations, then you will be in
trouble sooner or later.  Optimisations are not an on/off switch - they
are just an indication to the compiler about how hard it should work.
Optimisations that are "-O2" level on one compiler might be always
enabled on another toolchain.

Exactly the same thing applies to C - if there is any difference with
C++ it is only a matter of degree.

Of course it is not a good idea to push the limits of the language, the
tools, the optimisers, or the human programmers.  Understand that code
that behaves incorrectly when optimised is incorrect code - but you have
to strike a balance in order to find problems in a sensible timeframe.

Quoted text here. Click to load it

I have done so (not those particular newsgroups, but other sources).

I can understand that some programmers have a lot of difficulty with the
less obvious parts of C and C++.  And there are very few programmers
that don't have trouble at some point with the most subtle cases.  But
if a programmer is going to have trouble regularly when enabling
optimisation, then I would question the choice of C++ at all unless they
have more experienced co-developers to help find their mistakes.

Quoted text here. Click to load it

gcc (from around gcc 4.5 for a lot of the useful features - before C++11
was finish, and more complete support with later versions).

<http://gcc.gnu.org/projects/cxx0x.html

Of course, there is always a question of how complete is "complete" -
there are not many compilers that /fully/ implement all of C99.  But I
think gcc C++11 was "complete" in your sense by 4.7.

Quoted text here. Click to load it

Perhaps that's true, and if you know of others that are not mentioned
then bring them up.  I think some of /my/ "big points" can be
show-stoppers on the choice of C++ for embedded development projects,
while I did not see anything serious in the OP's original worries, and I
don't see /your/ worries about optimisations interacting with subtle
bugs as a big point.


Re: C++ syntax without C++

Quoted text here. Click to load it

I think that is the main issue for me. C is a very simple language, yet
it took me a long time to really know it. And there are still some
corners that are mysterious even now.

C++ seems pretty much impossible to learn fully (and I have been using
it for 10 years, on and off, for PC programming).

[...]

--  

John Devereux

Re: C++ syntax without C++
On 06/11/13 13:57, John Devereux wrote:
<snip>
Quoted text here. Click to load it

C is like the Japanese game Go - in theory, it is very simple, but in
practice it can be very subtle and complicated.

Quoted text here. Click to load it

C++ is certainly much bigger, especially if you include the libraries.
But like C, C++ is designed so that features you don't need and don't
use will not cost anything (the exceptions being exceptions and RTTI).

As long as you are programming by yourself, or within a team that agrees
on what they know and don't know, then you can simply pick the parts you
want to use.  If you don't need multiple inheritance and virtual
inheritance, then don't use them - just pretend they don't exist.  You
can do a lot by changing your .c modules to .cpp and then just gradually
adding bits of C++ that you think make your code better.  Remember your
aim - to write better, more correct code (or more /obviously/ correct
code) that is easier to understand, debug and maintain, and is hopefully
as small and fast or even better.  You are not being judged in a C++
contest - if all you use is strongly-typed enums then that's fine too.

For me, there have been a few things keeping me back from C++ for
anything more than experimental work in embedded systems.

One is that we used smaller micros, like the AVR - while the same code
will be as efficient in C++ as in C, non-inlined class member functions
are going to be inefficient due to the cpu's poor pointer support making
it hard to take real advantage of the language without high costs.  With
more ARMs (and some PowerPC) on our boards, that's not a problem any more.

Another is that C++ has had some issues where it is hard to get the
choice of features /just/ right.  For example, it is hard to make a
class that allows some conversions between different types while
disallowing others (the classic case being a conversion to bool to allow
if (x) tests without allowing conversion to other integer types).  C++11
gives you more control over that sort of thing.  In general, C++11 has a
number of small features that I think makes it a significantly better
language.

Toolchain support is awkward for many devices, especially for debugging.
 C++ support is often expensive (for CodeWarrior, it makes the
difference between free versions and $5000 versions - you need to get a
lot of benefits from C++ to justify that).  While gcc has excellent C++
support, it can sometimes be a bit of work to get particular gdb builds,
debugger hardware, and target devices all working correctly.

Finally, compilers (including my favourite, gcc) have been getting
better - error and warning messages are clearer, and code generation has
improved.  A key point is that LTO is getting solid enough that proper
modularisation should be possible (i.e., inline function definitions can
go in the cpp file rather than the header) - though I don't know yet
whether the result will be debuggable!


Different developers have different needs and preferences, of course,
but I think the language and the tools have reached the stage that C++
is a good choice for the sort of work I do.





Re: C++ syntax without C++

Quoted text here. Click to load it

I am programming by myself so that is fine for me.

Quoted text here. Click to load it

Yep, I don't see me using anything smaller than a M0 ever for a new
project, probably always M3 or bigger. An STM32F030 is $0.32 and I don't
design Christmas cards or Happy Meal toys.

Quoted text here. Click to load it

Yes I am going to have to experiment. The "gcc arm embedded" project
claims to support c++ out of the box but we will have to see.  

https://launchpad.net/gcc-arm-embedded

Quoted text here. Click to load it

One thing I disliked about the c++ "style" is having all variables used
by the class defined in the header.

Quoted text here. Click to load it

--  

John Devereux

Re: C++ syntax without C++
On 06/11/13 15:38, John Devereux wrote:
Quoted text here. Click to load it

The /compiler/ is no problem - gcc is an excellent C++ compiler with
good code generation (on most targets) and top-of-the-range support for
modern C++ features.  There can be some advantages to alternative
toolchains (IAR, Green Hills, Keil/ARM), depending on your needs, but
these are far from cheap.  And if you like some variety and a bit of a
challenge, LLVM is also an option.

The bit that can be difficult is getting the debugging hardware to work
along with your choice of chip and your choice of IDE.  In many cases,
you get your toolchain in a package with a debugger (usually gdb) and an
IDE (usually Eclipse), set up with support for certain hardware debugger
interfaces.  If the package supports the hardware you have got, or you
can get the hardware the package supports, it's easy.  If you happen to
have different parts, then you might have to do some work to get
everything to talk together.

Quoted text here. Click to load it

This is a fundamental limitation of the way the language works - to be
able to allocate objects, the compiler needs to know the details at
compile time, so all the members of a class need to be declared in the
headers.  The same applies to inlined functions - LTO technically
doesn't let you use inline functions from another module, it lets you
use them as normal C or C++ non-inline functions during compilation, and
then inlines them at link time.

There are ways around this.  You can put private class variables in a
separate header file and #include it in the main class definition, which
hides things a bit.  The PIMPL pattern uses a "pointer to
implementation" as the only private variable member of a publicly
visible class, and puts the real implementation class in a module - but
that means heap allocations and extra indirections for everything
(causing a big drop in code efficiency).  You can also do weird things
like have your class definition in the header have dummy data of the
right size, and use casts to cast to convert to the real data inside a
module - but that is even messier and uglier than PIMPL, although it
saves the heap usage.

Put more simply, a lot of people dislike C++'s limitations on
modularisation, but we are stuck with it!

Quoted text here. Click to load it


Re: C++ syntax without C++

Quoted text here. Click to load it

Sorry I should have been more specific, I meant particularly that the
linker and startup code explicitly supports c++. Some of the other/older
cross-gcc projects did not.

Quoted text here. Click to load it

I can't see the debug hardware being a problem (openocd driving the
dongle of the day for me).

Quoted text here. Click to load it

I suppose I am going to have to try eclipse again, each time I try it
seems slick and powerful yet when I need to actually get work done I go
back to emacs! :)

Quoted text here. Click to load it

For a long time I had been using the Insight debugger (a graphical
version of gdb). But recently I have switched to plain gdb, it seems
fine for my purposes once you get used to it. and comes with all the
toolchains. Also the gdb mode of emacs (my editor) for a more graphical
interface.

But if all the c++ symbols come out incomprehensible that is a
dealbreaker.

Quoted text here. Click to load it

But can the private header "add" members to the main class? Wouldn't you
have to #include the private .h from within the body of the class
definition in the public .h?

Quoted text here. Click to load it

You see that sometimes in C, especially with networking code when a
frame is binary data at a lower level but interpreted as a structure at
a higher level.
Quoted text here. Click to load it

[...]


--  

John Devereux

Re: C++ syntax without C++
On 07/11/13 09:51, John Devereux wrote:
Quoted text here. Click to load it

These are important too, of course.  But I think you'd have to go back
to a /very/ old version of gcc to see such problems.

There are some gcc targets with missing support for some parts of C++.
For example, the avr port does not support exceptions (AFAIK), because
no one has yet implemented the library functions to handle all the details.

Quoted text here. Click to load it

Changing religions is always difficult...

It's good to have choice.

Quoted text here. Click to load it

Insight is really just another graphical front-end for gdb - it just
happens to be linked directly with it, rather than running as a separate
process (like emacs gdb mode, Eclipse debugger, ddd, gvd, etc.)
Sometimes I like to Eclipse's debugger front-end to gdb, sometimes I
like to use "pure" command-line gdb.  It depends on what I am doing at
the time.  Again, choice is good - you are not limited to one or the other.

Quoted text here. Click to load it

gdb should handle the name mangling/demangling fine.  Overloading can
make it difficult to identify functions easily (i.e., "b foo" to put a
breakpoint on foo() - which foo() are you talking about?), but you get
that in C too if you have multiple static functions with the same name.
 In such cases, a gui for point-and-click breakpoint settings is
probably easier.

Quoted text here. Click to load it

No, and yes.

Quoted text here. Click to load it


Re: C++ syntax without C++

Quoted text here. Click to load it

Yes I expect it was avr I was thinking of.

Quoted text here. Click to load it

[...]

Quoted text here. Click to load it

That's all right then.


Quoted text here. Click to load it


[...]

Quoted text here. Click to load it


OK, thanks.

[...]


--  

John Devereux

Re: C++ syntax without C++
Quoted text here. Click to load it

I used to be a Insight user for many years as well until Insight
development stopped, at which point the tightly integrated front end
became a liability which bound me to a increasingly older version of
gdb. I also wanted more flexibility with cross compiled/remote target
debugging.

After looking around I switched to ddd, which, while clunkly, works well
for my needs. You can use the same ddd front end binary with both native
gdb and cross compiled gdb binaries because you can specify the back end
gdb binary to run on the command line.

Simon.

--  
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

Re: C++ syntax without C++

Quoted text here. Click to load it

Yes me too.

Quoted text here. Click to load it

I must look at DDD again some time, something stopped me last time I
looked into it.

DDD = "data display debugger" IIRC. Recently I found a way to get some
nice plots out of gdb, just a few-line script to dump an array, say,
into gnuplot. You can get nice "scope plots" of the contents of an ADC
result array, or a histogram of same etc. Really nice for a program that
analyses signals (like mine tend to do). It even works while the program
is running!


--  

John Devereux

Re: C++ syntax without C++
John Devereux wrote:

[...]

Quoted text here. Click to load it

...if the gdb server supports the asynchronous mode, I guess? Segger
didn't last month.

BTW: Watching variables at runtime is IMO a basic feature, I'm using
it since Motorola HC12 times.

Oliver
--  
Oliver Betz, Munich
despammed.com is broken, use Reply-To:

Site Timeline