Wednesday, July 4, 2018

Digest for comp.lang.c++@googlegroups.com - 12 updates in 3 topics

Thiago Adams <thiago.adams@gmail.com>: Jul 04 11:24AM -0700

On Wednesday, July 4, 2018 at 9:34:54 AM UTC-3, Thiago Adams wrote:
[...]
> When the tool is too hard to operate and gives you a lot
> of options it also can become dangerous or unpractical to learn
> /teach and use.
 
This is a sample of "compiler mechanics knowledge" to work
with C++.
 
http://ibob.github.io/blog/2018/07/03/compiler-generated-move/
Bo Persson <bop@gmb.dk>: Jul 04 10:09PM +0200

On 2018-07-04 20:24, Thiago Adams wrote:
 
> This is a sample of "compiler mechanics knowledge" to work
> with C++.
 
> http://ibob.github.io/blog/2018/07/03/compiler-generated-move/
 
So to have a dynamic array of structs storing generic function objects
holding lambdas, all with its own variable set of data values, you might
have to know what you are doing.
 
And the code ends up being this advanced:
 
struct simple_struct
{
simple_struct() = default;
simple_struct(simple_struct&&) = default;
simple_struct(const simple_struct&) = delete;
 
std::function<void(int)> func;
std::vector<int> data; // call func with each element in data
std::unique_ptr<complex_struct> more_data;
};
 
 
 
Now, how do you do this in C?
 
 
 
Bo Persson
Thiago Adams <thiago.adams@gmail.com>: Jul 04 02:16PM -0700

On Wednesday, July 4, 2018 at 5:10:00 PM UTC-3, Bo Persson wrote:
> std::unique_ptr<complex_struct> more_data;
> };
 
> Now, how do you do this in C?
 
I think in C (or in C++ using less abstractions)
it is hard to give the answer without to
know all the details. For instance, is really
necessary to have variable capture inside func? If not,
a simple function pointer works.
Is necessary resize the data after creation? If not,
a simple pointer and size is enough. Sometimes just
a pointer with zero-ended is also an option.
Is data size something small that we could make fixed
size and avoid allocations?
The concept of move in C would be just a normal copy
and the programmer knows that the ownership has been
transferred.
 
To make the solution more direct or more "flat" sometimes
is important to ask more questions and restrict the scope.
Bart <bc@freeuk.com>: Jul 04 06:12PM +0100

On 04/07/2018 14:19, David Brown wrote:
>> msvcrt.dll, then my opinion as to the relevance of all this junk may
>> well be different to yours.
 
> Your problem is that you like to write "hello world" programs,
 
These days I write, in static code, programs such as compilers,
interpreters, assemblers, 'linkers' and libraries such as for image
processing.
 
Programs with file input and file output. I don't think they are that
unusual. The requirements are for the simplest of linkers - what would a
more sophisticated one bring to the table?
 
For programs involving GUIs and such, those are based on dynamic code
where linkers do not exist at all.
 
and get
> specifically to suit /your/ personal needs and wants. You only want a
> tool that compile "hello world", and maybe stretch to programs with 2 or
> 3 source files
 
(I've tested my assembler-linker with 10,000 small, dummy files,
producing a 0.6MB output. It managed it in 0.6 seconds. Don't forget
that's /assembling/ 10,000 files then combining the results. 100,000
files, however, need some attention... )
 
- other people want a compiler that works well for
> programs with hundreds of thousands of source files and hundreds of MB
> of code.
 
I would say that most people developing applications are not using
hundreds of thousands of files of source code. Even the gcc sources only
use 45,000 files! And those don't all go into a single executable either.
 
So it's possible that current linkers for such people are over-specified.
 
I don't actually care about the matter or whether people choose to use
archaic tools, but I had a need for a linker and all the options
available each had their problems.
 
Now it's true that heavy duty programs intended to work at a big scale
need special design and special considerations. However many, many
applications don't require that scale of program and this is where my
stuff comes in.
 
You only need a subset of an ancient C standard - other people
> PC that was outdated decades ago, when it is possible to for a limited
> toy tool to work in a fraction of a second. Speed doesn't matter when
> your tool can't do the job other people need.
 
Tell me what other people need out of a linker. If it's link-time
optimisation, then that's a feature that really belongs in a compiler,
not a linker. Or at least it is a different kind of tool.
 
What /I/ call a linker is combining multiple, independently compiled
modules into one binary file. It /is/ that simple.
 
--
bartc
Ian Collins <ian-news@hotmail.com>: Jul 05 08:29AM +1200

On 04/07/18 22:45, Bart wrote:
>> incremental linkage.)
 
> Linking is something I could never understand why it was such a big deal
> or why it took so long.
 
It isn't and doesn't with modern tools.
 
--
Ian.
Soviet_Mario <SovietMario@CCCP.MIR>: Jul 04 04:14PM +0200

Il 03/07/2018 14:42, Paavo Helde ha scritto:
> error: undefined reference to
> `clsDiskMap::FzScanPathFoldersRecursively(QString const&)'
 
> 'undefined reference' means a linker error.
 
oh, one thing solved, at least ! TY
 
> once containing member function declarations and the second
> time definitions. This is a violation of the ODR (one
> definition rule) and will cause UB.
 
this makes me wonder what MUST NOT be declared in headers ...
I put the prototypes (of member functions), that is the
declarations of parameters and return type (I did not erase
the NAMES of formal parameters ... is this relevant ?), but
in the header I removed the BLOCK with the function body,
and semicolon after closed ")".
 
In the CPP file there where the same declarations (but
without semicolor) were followed by the block of code
(function body) which I thought makes a true definition.
 
 
 
> Instead, the member function definitions should go into the
> cpp file without no enclosing class:
 
I'm not sure to be understanding what you mean).
 
Do I have to move the (MEMBER) function BODIES outside the
class braces ? Why this, in the same file, changes
visibility to the linker ?
 
 
> // clsDiskMap.cpp:
> #include "clsDiskMap.h"
 
another thing I don't understand.
Generally I include the XXX.H header only in OTHER CPP
files, not in the same XXX.CPP.
Is this wrong ? HOW the "self" header helps to see itself ?
 
Sorry but I'm very rusty, I'm not using this language since
2004 or so, yes I read some material to refresh, but not
everything.
 
You confirm that a generic XXX.CPP needs its "same" header
XXX.H ? Would you also mind to try to explain me why this ?
 
TY
 
I try to experiment meanwhile ...
 
 
--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)
Soviet_Mario <SovietMario@CCCP.MIR>: Jul 04 04:26PM +0200

Il 03/07/2018 01:40, Sam ha scritto:
>> plain without errors.
 
> So far, you've provided no evidence that compilation order
> matters.
 
hey, friend, I was only suggesting and asking for advice, I
was never stating it was or should be ...
 
>> There might be other aspect in declarations I miss / forgot
>> (like extern directives ?)
 
> Declarations have nothing to do with compilation order.
 
ok. Better so !
 
> so the next file gets compiled as soon as one of the current
> modules finishes compiling; so the compilation order varies
> slightly, every time.
 
If you happen to read the reply of Paavo Helde, or mine to
his, can you clarify me which part of the CPP file must be
stripped in creating the corresponding headers ?
 
In particular, about function declarations, I assumed that
just stripping away the function BODY (in braces), generated
a forma declaration.
Paavo suggests that, moreover, in CPP files, the body
definition should be moved from within the class body, outside.
I'm not understanding this and how it influences linking.
 
If I manually merge the files in one, even leving function
definitions within their class block, works.
 
Why does it no longer work splitting the project in more files ?
 
I can't find the difference of defining a function entirely
within a class body or just declaring it (like in the
header) and then defining out of the class body (using the
prefix ClassOwner :: MemberFunction (...) { ... };
 
 
 
> If you are seeking assistance with your compilation
> troubles, it will be necessary to provide something more
> substantive than vague memories and recollections.
 
I attached the whole code as you can see.
Maybe Paavo Helde has just found a flaw in it.
 
 
>> I'm asking in order to understand
 
> All C++ books provide detailed information about scoping,
> and how header files work. If there's
 
I missed this details both on paper book and in some C++
reference online ... that's why i'm trying to resort to the NG
 
 
>> I tried to explain with a generic example ... I dunno if it
>> will be useful
 
> No, it's not. "Generic examples" are rarely useful. What is
 
Ok, I was wrong, but later I posted the complete code.
If this can't help, well, tnx anyway for your time (and bye)
 
ciao
 
 
--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)
Paavo Helde <myfirstname@osa.pri.ee>: Jul 04 06:20PM +0300

On 4.07.2018 17:14, Soviet_Mario wrote:
> parameters and return type (I did not erase the NAMES of formal
> parameters ... is this relevant ?), but in the header I removed the
> BLOCK with the function body, and semicolon after closed ")".
 
Compiler sees "compilation units", which are typically cpp files merged
with all included headers. If there are two class definitions in such
files they must be textually identical. So you cannot have it contain
member functions in one case and not in the other.
 
> In the CPP file there where the same declarations (but without
> semicolor) were followed by the block of code (function body) which I
> thought makes a true definition.
 
True, but as you messed up the class definition the linker got confused.
>> without no enclosing class:
 
> I'm not sure to be understanding what you mean).
 
> Do I have to move the (MEMBER) function BODIES outside the class braces
 
Yes.
 
 
> ? Why this, in the same file, changes visibility to the linker ?
 
Who knows. UB means "undefined behavior", meaning the linker can legally
call your mom and complain about you ;-)
 
> Generally I include the XXX.H header only in OTHER CPP files, not in the
> same XXX.CPP.
> Is this wrong ? HOW the "self" header helps to see itself ?
 
You definitely need to include XXX.h in XXX.cpp, otherwise the member
function definitions would not compile - because the class would be
undefined. And you cannot put them inside class XXX {...} as this would
create a second incompatible definition of the class.
 
Suggesting to find a C++ tutorial explaining those things...
Soviet_Mario <SovietMario@CCCP.MIR>: Jul 04 07:11PM +0200

Il 04/07/2018 17:20, Paavo Helde ha scritto:
> On 4.07.2018 17:14, Soviet_Mario wrote:
>> Il 03/07/2018 14:42, Paavo Helde ha scritto:
 
so I applied your advices but one (the "self" inclusion of
the header).
 
Now it compiles and links the project without complaints.
 
I deem that the .CPP unit compiles smoothly even in the
absence of his equivalent .H because there are not circular
references and the only dependences are "friendship"
declarations solved with a plain forward declaration.
Maybe in the presence of more complex class hierarchy the .H
file could be necessary, I don't know.
Or else, the QT is not completely standard, as sb said
elsewere, and it allows compiling A.CPP who dont include A.H ...
 
I had to make also a lot of small edits in STATIC members
and extern declarations.
Alas even if now it works, I must admit I've not understood
well WHY and how, even after reading.
 
Anyway as a question of style, I'll try to put the function
out of the class.
I kept inside just a few function with an only one statement
of kind "return Varname;", but in this case I also added
INLINE prefix.
 
> files merged with all included headers. If there are two
> class definitions in such files they must be textually
> identical.
 
oh but they did seem such to me, but, evidently ... :\ they
were not or were wrong.
 
If intresting, I could post again the full code modified ...
I guess nobody would be interested in (it is just in
embrio-state after all)
 
>> thought makes a true definition.
 
> True, but as you messed up the class definition the linker
> got confused.
 
eh ... it's a bit sad to have solved without having actually
understood how.
But it is simpler to keep it compiling by applying small
changes and testing than to strip away the damned last
couple of errors that prevent to get the very first
buildable solution, starting from scratch with a code that
had never been compiled successfully ... some 12 years after
the last use of the language (and on a brand new, for me, IDE).
 
I was on VStudio and VB/C# for a long time (and coding only
from time to time actually), and now that I've passed on
linux and QT, a thousands of problems have been to be solved
to get this piece of code showing up in a window with a
couple of buttons :)
 
>> linker ?
 
> Who knows. UB means "undefined behavior", meaning the linker
> can legally call your mom and complain about you ;-)
 
mmm, as a matter of facts, either the inline directive amend
that mandatory feature, or QR creator allows in some cases
(don't ask me when !), or both, but actually the code
compile and link with some very trivial function embodied in
the class body.
 
 
> You definitely need to include XXX.h in XXX.cpp, otherwise
> the member function definitions would not compile - because
> the class would be undefined.
 
sorry I don't understand the point (and I have NOT included
it, and still it links ...)
 
MAYBE this is due to the fact that the declaration was
maintained ALSO in the .CPP unit, which actually replicates
the header declarations ... with the exception of STATIC
(shared in VStudio terms) members and (shared) member
CONSTS, which are defined only in the CPP module.
 
oh, one thing : member variables are "indifferent", that is,
I can declare them or not in the .H, and nothing changes on
build.
They are all private and just a CONST shared public.
 
I think this is due to the fact that they are not
definitions, don'allocate anything, they just describe the
shape of the container.
 
I can't think of situation where :
1) such variable members declarations WERE NECESSARY in the
.H (and if public, protected or private, or any)
2) such variable members declarations WERE FORBIDDEN in the
.H (and if public, protected or private, or any)
 
for now it seems INDIFFERENT, but I'd be glad to understand
if the aforementioned cases exist with some example ...
 
 
> class XXX {...} as this would create a second incompatible
> definition of the class.
 
> Suggesting to find a C++ tutorial explaining those things...
 
Oh I'm reading some material from StackOverflow and
elsewhere ...
 
TY
Ciao
 
--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)
Paavo Helde <myfirstname@osa.pri.ee>: Jul 04 08:51PM +0300

On 4.07.2018 20:11, Soviet_Mario wrote:
>> On 4.07.2018 17:14, Soviet_Mario wrote:
>>> Il 03/07/2018 14:42, Paavo Helde ha scritto:
 
> so I applied your advices but one (the "self" inclusion of the header).
 
Then it probably got included indirectly via another header.
 
> Now it compiles and links the project without complaints.
 
Good!
 
> equivalent .H because there are not circular references and the only
> dependences are "friendship" declarations solved with a plain forward
> declaration.
 
'Circular' and 'friend' only come into play if you have more than one class.
 
> class.
> I kept inside just a few function with an only one statement of kind
> "return Varname;", but in this case I also added INLINE prefix.
 
This is redundant, member functions defined inside the class definition
are already implicitly considered 'inline'.
 
Cheers
Paavo
Soviet_Mario <SovietMario@CCCP.MIR>: Jul 04 08:14PM +0200

Il 04/07/2018 19:51, Paavo Helde ha scritto:
 
>> so I applied your advices but one (the "self" inclusion of
>> the header).
 
> Then it probably got included indirectly via another header.
 
no, actually not.
But, as I said, I'm likely to have duplicated the header in
the CPP file, as EVERYTHING declared in the header, is also
declared (besides defined) in the CPP.
I guess a CPP module is added at most once regardeless of
safeguards #indef / #define /

No comments: