Thursday, November 28, 2019

Digest for comp.lang.c++@googlegroups.com - 25 updates in 6 topics

James Kuyper <jameskuyper@alumni.caltech.edu>: Nov 25 11:45AM -0500

On 11/23/19 5:12 AM, Soviet_Mario wrote:
> Il 23/11/19 05:56, James Kuyper ha scritto:
>> On 11/22/19 6:25 PM, Soviet_Mario wrote:
>>> Il 22/11/19 20:11, James Kuyper ha scritto:
...
 
> I find this type (everyone might guess it is equivalent to
> the other), u_int8_t, which finally stems from a typedef to
> UNSIGNED CHAR.
 
Please do not change the capitalization of the characters in C++ code.
As I keep telling you, C++ is a case-sensitive language. If UNSIGNED
CHAR even exists, in principle, it's not necessarily related in any way
to unsigned char. In practice, there's likely to be a connection, but if
anyone did bother creating, for instance, macros with those names, the
connections is unlikely to be a simple one. In such as case, they
probably defined those macros precisely because there are circumstances
where they do NOT expand to "unsigned char".
 
Such names as u_int8_t are, as far as C++ itself is concerned, reserved
for use by user code. However, POSIX reserves identifiers ending in _t
to itself to represent types, and sys/types.h is not a C++ standard
header, so I that makes it legal for that header to declare such
identifiers. However, I can find no mention of them in the Single UNIX
standard, so I've no idea why they actually are declared. There's
certainly no good reason for using them rather than uint8_t for this
purpose.
 
 
>> Whatever is the source of this typedef, I don't think it's QT.
 
> omg ... are you saying I am just lieing for the fun of it ???
 
No, I'm just assuming that you're confused. Using u_int8_t rather than
uint8_t, just because such an identifier exists, tends to justify such
assumptions.
Keith Thompson <kst-u@mib.org>: Nov 23 05:06PM -0800

>> definition) or anywhere under /usr/include on my system.
 
> yes I miss-spelled forgetting the final _t (but the pieces
> of headers pasted mentioned it)
 
To be very clear, if you need an unsigned integer type of at least 8
bits, there is almost no good reason not to use uint8_t. There is no
good reason to use some system-specific (or even undocumented)
equivalent.
 
"Almost" means you might have to consider older implementations that
don't support <stdint.h> / <cstdint>. Any version of g++ you're likely
to encounter should support C++11 or later -- older versions might
require an explicit option. Even older versions are likely to support
<stdint.h> or <cstdint> as an extension.
 
> and C++ engine.
 
> I'll never deploy the program anywhere else. So as long as
> it compiles here, fine enough
 
If you use uint8_t it will compile.
 
 
>> What warnings?
 
> that anonymous structs (or unions) are non standard and
> supported only with GCC later than some version.
 
It's always better to copy-and-paste diagnostic messages rather than
trying to summarize them.
 
BTW, I made a serious mistake here. C supports anonymous structs as
of C11. C++ does not support them at all. g++ does support them as
an extension. With "g++ -std=c17 -pedantic", I get "warning: ISO C++
prohibits anonymous structs [-Wpedantic]". My apologies for that.
 
If you're only using gcc, you can use anonymous structs in C++,
but your code will be non-portable.
 
[...]
 
> instead of four of them.
> But if struct can be assigned smartly enough then the union
> is not needed.
 
The semantics of struct assignment (assuming you haven't overloaded
operator=) are equivalent to the semantics of copying memberwise,
but in the case of a struct containing 4 uint8_t members, no sane
compiler will do anything other than a 32-bit copy. That's assuming
the struct has an alignment that permits a 32-bit copy.
 
If copying the entire structure is the only operation you care about,
keep it simple: just define the structure and use ordinary structure
assignment.
 
[...]
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
Keith Thompson <kst-u@mib.org>: Nov 23 12:27PM -0800


> again ...
> Keith, I did not edit the header manually, and sized ints
> HERE are spelled as I wrote.
[SNIP]
> as you can see the types are spelled as I wrote them, and a
> search for uintXX_t does not find anything
 
I didn't know where the names u_int_8 and u_int_32 came from,
and assumed they were misspellings of uint8_t and uint32_t.
 
On my own system, #include <sys/types.h> introduces the non-standard
type names u_int{8,32}_t. It doesn't introduce u_int_{8,32}, and I
don't see that name in the code you quoted (other than in your union
definition) or anywhere under /usr/include on my system.
 
On the other hand, the types uint8_t and uint32_t are defined by the C
and C++ standards (starting with C99 and C++11, respectively).
 
Nobody is suggesting that you're lying or manually editing headers. All
we're saying is that uint8_t and uint32_t are the *standard* types that
meet your requirements, and there is no good reason to use non-standard
types with similar names.
 
Do you have some reason to prefer to use u_int_8 rather than uint8_t?
 
> is this that big problem ?
> I guess the variations stands for the same concept
 
Yes. Names other than uint8_t are non-standard and will cause your code
not to compile in many environments.
 
 
>> C11, so older compilers might not support it, or might not support it
>> by default.)
 
> it gives me warnings indeed, but seems to compile nevertheless
 
What warnings? If you compile with "gcc -std=c11" or with a
sufficiently new version of gcc, there shouldn't be any.
 
Always pay attention to warnings.
 
[...]
 
>> between members or after the last one,
 
> and that was the reason why I had thought of trying to give
> it a strong hint not to pad by mean of a #pragma pack directive
 
If it works without a non-standard #pragma pack, why would you add it?
You risk your code failing to compile, or compiling incorrectly, with an
implementation that doesn't support #pragma pack or that does something
unexpected.
 
> approach
 
> I thought : I give you an hint : TRY to pack. If you really
> cannot, there is nothing else I could do
 
There's no guarantee that all compilers will understand your "hint",
and nothing in the standard that says anything at all about what
"#pragma pack" does.
 
[...]
 
 
> and I don't need such warranty : I use AllChannels only for
> mass-copying, assignments, copy constructor. When I need
> access to separate channels I use named members.
 
What operations do you need on AllChannels that you can't perforom on
the struct? You can assign structs.
 
[...]
 
> other more general examples with longer integers
> hypothetically spanning non multiple addresses : here I have
> 1 byte sizes, and the only big member starts at 0 offset)
 
The drawback of #pragma pack is that it's non-standard. Given the
concern you've expressed about portability, I would think that would
be important to you. And given that it will almost certainly do
nothing, I don't know why you're so insistent on using it.
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
Christian Gollwitzer <auriocus@gmx.de>: Nov 22 07:26AM +0100

Am 21.11.19 um 17:20 schrieb Paavo Helde:
> than char. For example, long is 32 bits in 64-bit MSVC and 64 bits with
> 64-bit gcc on Linux.
 
> However, for your purposes std::uint32_t should work fine.
 
Why not
 
#pragma pack(1)
struct pixel {
uint8_t red, green, blue, alpha;
}
 
? That would make more sense to me than uint32_t and bit-twiddling to
get the channel values.
 
Christian
Soviet_Mario <SovietMario@CCCP.MIR>: Nov 22 01:14PM +0100

Il 22/11/19 12:23, David Brown ha scritto:
> than looking at what is actually relevant or helpful. At the moment,
> you haven't the faintest clue as to whether using a packed struct makes
> a real and measurable difference that is worth the cost -
 
sure I have no idea, I put the pragma there just for
"precaution"
what cost is that supposed to have ?
 
 
> timings of real-world usage of your system to see if this is a
> bottleneck. You haven't tested alternatives like "mmap", or existing
> libraries.
 
I'm writing from scratch almost, but It will be a very
simple library
 
> You haven't compared the time it takes to load or save the
> file with the time it takes to do your processing.
 
sure, but I'll have to do both in any case :)
It's a non-sense comparison though
I just thought of
read/write all-at-once vs pixel by pixel (and choose I)
 
no use in knowing if I spend more time applying
transformations on the loaded picture vs saving or loading
it. They are sequential mandatory operations
 
 
> You haven't compared
> the time it takes to pack or unpack the format to the time it takes to
 
chosen not to pack/unpack anything actually, as I'm hoping
the RAM / disk layout are the very same raw binary.
I was asking help in making sure this was (not if it was
useful or not)
 
> read or write it from the disk. You haven't compared the time the
> processing takes for a "packed" struct to how it would run with an
> unpacked struct.
 
forgive me : how to read an all packed file in an array of
UNpacked data of different layout, in a single read
operation ? I can't figure out this
 
 
> (Yes, I realise I have made a lot of claims here about what you have and
> haven't done. From your posts, I think they are almost certainly true.
> If I am wrong there, let me know.)
 
no problem, most are right.
Some are irrelevant imho
 
 
> If you want to tell me that using "pack" makes your development process
> simpler and the code easier, that's fine
 
I don't know. Just searching a way to do binary read/write
in one single shot directly to/from RAM without any conversions.
And have a RAM layout simple enough not to require bitwise
masking to locate fields (the drawback of a pure "bit
fields" solution)
 
> doing it for run-time speed reasons, then you are wrong. Measure first,
> find out if it really is too slow, find your /real/ bottlenecks, /then/
> start looking for ways to improve the throughput.
 
I don't have any running stuff by now, as I'm still in the
design time.
But I could not redesign the BASIC disk and data structure
later, so i MUST make some premature optimization now as it
affects the very base of the pillar.
 
>> this directly. When in gambas I save using its native functions. The C++
>> engine is just supposed to transform pictures and save in raw format.
 
> So don't make stupid formats. Make /simple/ formats,
 
I meant the same actually.
I store 16 bit width, 16 bit height, and then a compact
rectangular array o 32 bit pixels (8+8+8+8 for 3 color
channels + transparency) per each pixel.
 
it is is not completely "naturally aligned", but the header
and the "body" are placed apart, in memory, and read/written
in distinct file operations.
 
So I ask you, when I call NEW operator for an array of
"pixel" structs, is it naturally aligned or not ?
 
 
> and non-standard
> formats, if that is what is best for the job. But don't make a stupid
> format.
 
I called it stupid in place of the simplest as possible.
There are no "tags" included as this is only an "internal"
(and personal) format for intermediate raw data.
It does not seem to be more sophisticated than this.
 
 
--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)
David Brown <david.brown@hesbynett.no>: Nov 24 08:53PM +0100

On 22/11/2019 19:35, Soviet_Mario wrote:
> Il 22/11/19 15:04, David Brown ha scritto:
>> On 22/11/2019 13:14, Soviet_Mario wrote:
>>> Il 22/11/19 12:23, David Brown ha scritto:
 
<snipping quite a bit to cut down on the size of the post>
 
 
> In that case either pragma is USELESS (and hence does not produce any
> reasonable effect, neither slowness), either is NECESSARY (and so the
> slowing effect is a unavoidable price that I MUST pay either)
 
A "pack" attribute is unlike to have any effect when you have only
uint8_t types in a struct or array. There is a hypothetical possibility
of it affecting padding or alignments on the struct as a whole, but that
will definitely not apply for any platform "normal" enough to support
QT. But have no positive or useful effects does not guarantee that you
will get no negative effects in terms of efficiency or what the compiler
allows for the code, and certainly you will still have the negative
effects of non-portable code and confusing source code.
 
 
>> "Packed" is /not/ a
>> "precaution", nor is using a struct with a bitfield instead of uint8_t.
 
> the second part has been abandoned early
 
OK.
 
> 1995-2000 roughly, then less and less afterwards.
> But strangely enough, I find it more easy to think in C++ terms when I
> met problems in basic.
 
OK.
 
 
>> So /ask/ (and please read the answers).  Don't guess, or grab the first
>> thing that you find from a google search.
 
> but I DID follow the answers :)
 
I saw a lot of posts indicating that you either didn't read the answers,
didn't understand them, didn't agree with them, or at least did not rate
them as reliable sources of information. There have been so many posts
in this thread that it is hard to have an overview, but I believe you
made several "I'm keeping pragma pack as a precaution" posts after
having been told how it is worse than useless. But maybe I have a false
impression here, based on the order of reading posts or details of what
were written.
 
>> people in a group like this all say "don't use packed" and "use
>> uint8_t",
 
> I didn't read or desume the two things should be mutually exclusive.
 
I can see how that might not have been clear at the start.
 
 
> 1) added pragma (to the four u_int_8 members in a struct) is USELESS, as
> the struct was just packed natively (and hence does not produce any
> reasonable effect, neither slowness),
 
Yes, it is useless here.
 
> 2) is NECESSARY, as the struct would not have been natively packed
> otherwise (and so the slowing effect is a unavoidable price that I MUST
> pay either)
 
When you have understood what "packed" does, and how compilers handle
structs, you will realise that this will not be the case. (Any
compiler/target combinations sufficiently odd that uint8_t structs are
not tightly packed anyway, are unlikely to support "pragma pack", almost
guaranteed not to support QT, and are definitely not platforms you will
be using anyway.)
 
> either
> 3) it is NOT SUFFICIENT (in this case, luckily unlikely, nothing would
> have worked fine at all)
 
Correct.
 
But you have missed the fact that there are potential disadvantages in
using "pack" even when it offers no advantages.
 
> The packed (natively or forcefully) struct is 32 bit wide, so allocating
> an array should allow nice addressing of any item even on a 64 bit OS
> And no item would cross critical addressing boundary
 
The struct will be 32 bit in size, but the alignment will be one byte.
Whether you consider that an advantage or disadvantage compared to four
byte alignment depends on how it will be used.
 
>> useless, when it is worse than useless,
 
> If you have some further patience, tell me if the 3 scenarios fit the
> present situation (not a more general one, but just this)
 
Hopefully my reply above covers this.
 
 
>> "Packed" is not a precaution -
 
> I call it a precaution as it reduces the chances of a non packed data
> layout.
 
It does not do that - the chances of the uint8_t data not being packed
are 0, and "packed" does not reduce those chances. Therefore it is not
a "precaution".
 
 
> without PRAGMA, do I have any explicit or implicit warranty that my
> union be 32 bit long ? If so, PRAGMA is useless. If not, it seems it
> might be useful.
 
If you keep using non-standard types, then we can't be entirely sure. I
know what the standard types "uint8_t" and "uint32_t" are, but I have no
definition for "u_int_8" and "u_int_32". I /assume/ they are defined
like the standard types, but you might have made a mistake. I strongly
recommend you don't use home-made types like this when there are
perfectly good standard types available.
 
The C and C++ standards give implementations a lot of freedom about
packing, padding and alignments in structs and unions. But practical
implementations do not do anything weird unless they have good reason
for it. When you are talking about mainframes, supercomputers, DSPs, or
particularly odd niche processors, you need to be careful and check the
details. For ordinary computers, and code that would never be used on
anything else, there is no problem. (For a guide, anything targetting a
POSIX or Windows system, or any embedded system supported by gcc or
clang, there will be no problems.) On such "ordinary" targets, all
basic types are 8-bit, 16-bit, 32-bit, 64-bit or 128-bit, and the
alignment of those types is at most equal to their size. (It can be
smaller, however, if the "bitness" of the cpu is smaller than that
size.) No padding is added except to make sure each struct member is
aligned, and that the struct itself is aligned by the biggest alignment
of any member.
 
 
> what damages could PRAGMA PACK produce ?
 
I've told you already.
 
> If the union would be just packed natively, I guess none.
 
No.
 
It /might/ be the case that the only disadvantages of "pragma pack" are
lack of portability to other tools on the same or similar platforms, and
confusion for the reader as to why you have added this useless pragma.
 
But it is also possible that it will restrict what you can do with the
struct (like taking the address of the members), it can lead to errors
that are not diagnosed (like letting you take the address of the
members, but those addresses not being aligned and this leading to
subtle problems when the compiler assumes they /are/ aligned), it can
lead to inefficiencies (like compilers generating byte-by-byte access to
larger fields on some targets) or compilers being pessimistic about
optimisations.
 
> If it wasn't, at best it would pack it (and maybe slow it, but this is
> irrelevant, I need precise disk layout).
 
If the union was not packed natively, you'd be working on a very odd
system and "pragma pack" would not apply anyway.
 
> In this last worst case, are there any other means of getting the thing
> to work ?
> What are them ?
 
If you are dealing with a system where you can't be sure your simple
arrays and structs are packed sensibly (at most padded for "natural"
alignment), you can't handle it this way anyway - you are going to have
to write code that manually unpacks the raw stream of byte data.
 
<snip>
 
> I said :
> 16 bit (width) - 16 bit (height) - N x 32 bit (R,G,B,alpha)
> where N = width x height = number of "pixels"
 
That does not tell us anything about alignment. Are your fields
properly aligned or not?
 
 
> every pixel is multiple of 32 address on file (but this seems irrelevant
> to me).
 
I presume you mean multiple of 32 bits, i.e., 4 bytes. And yes, this is
/highly/ relevant. It means your data is well aligned, and you can use
a union with a uint32_t for your pixels (if you want). Are you also
sure that your 16-bit values (height and width) are 16-bit aligned? As
long as all your elements are naturally aligned, then the struct is
properly aligned and you can use a plain, simple struct with no "packed"
complications.
 
This is /critical/ to being able to support your structure simply,
cleanly, efficiently and portably. That is why I have repeatedly asked
you if your format is properly aligned.
 
> transparency is more than needed ... but taking less is useless or
> impossible, and 1 byte is natural for the otherwise 3,sth bytes long
> struct)
 
I haven't suggested using smaller types for your data - I assume that
these are appropriate types.
 
> oriented internally (and the OS does caching independently and
> transparently, basing on disk cluster sizes but this is not sth I should
> care of)
 
It does not affect the file reading and writing - it affects the struct
in memory that is accessed by the code. C and C++ only define access to
correctly aligned objects and subobjects. Access to unaligned data is
implementation dependent, may require extra extensions (like pragma
pack), may be subject to various restrictions, may be inefficient
(either extra code, or inefficiencies in the cpu processing), and may
cause problems if the data is used with third-party libraries or code.
 
>> alternatives.
 
> for a starting, I tried to use a 32 bit total size, hoping it would have
> been packed regardless of any "hints" (pragma).
 
That is a good plan. When you do that, you avoid any need for "pack"
extensions.
 
It appears that you have designed a /sensible/ file format. It is
/simple/, but certainly not "stupid". It has taken a while to get you
to give enough details to establish this, but it seems to have been a
sensible format all along.
 
What you have got wrong is your determination to distrust your own
sensible decisions in the file layout and add worse than useless extra
"pack" junk. Forget "pack" - forget you ever heard of it. It is not
part of the C++ language, it is rarely useful, and it is certainly not
useful here. Just use your file format in the clear, sensible layout
you have designed.
 
 
> it is, as both Gambas supports BYTE format (And sizeof()) and
> BYTE-oriented streams. No overspace is generated. Then I have to worry
> about the C++ back end, to comply with this fact.
 
My knowledge of Gambas is very limited, but according to the
documentation I found its structs are /not/ packed:
 
<http://gambaswiki.org/wiki/lang/structdecl>
 
Padding /is/ generated - if needed to get the natural alignment of the
fields. You can be entirely confident that on any platform supported by
Gambas, the padding, alignment and layout of a Gambas struct and a C++
struct will be the same.
 
 
> I think the designer of Gambas relies very strongly upon C libraries and
> mind-shape, apart from strings (where he had to welcome BASIC users who
> want strings the basic way).
 
Of course. And while the details of C struct layouts is implementation
dependent, it is invariably the simplest and most obvious but efficient
layout for the target.
 
>> padding in a normal struct.  I have seen no answer to this (unless it is
>> later in this post), despite asking this /crucial/ question.
 
> the files are packed.
 
The information you have given so far in this post suggests they are
properly aligned. They are without padding, but that is because of the
field sizes used and their arrangement, not because you have
specifically asked for non-standard packing.
 
> such FAST temporaries to be shared, but with portable stream syntax).
> Using /shm would imply no specialized load/store code, just the normal
> file access => delegating the ram usage to the OS.
 
If your files are in a ram file system (/shm, tmpfs, etc.) then memmap
would not be faster anyway.
 
 
>> If the format is bad, the next step is to consider changing the format.
 
> just observation.
> So, the format is wrong ?
 
/You/ tell /me/. Only /you/ know the full format. But from what you
have said here, the format is probably fine.
 
>> formats.  Reader and writer functions are common for all sorts of
 
> well, I'd be considering these for small size, complex structured input,
> not for a 4-12 MB size of simple pixels. It would be a blood bathe
 
You are basing that on speculation with no evidence.
 
I am not at all saying that it is a bad idea to use a direct mapping
from file format to struct - indeed, it is a sensible idea whenever you
can define the format.
 
As far as I understand your project, you are using Gambas for a gui but
for some kind of image processing, you are saving the pictures from
Gambas as files, then starting an external C++ program that reads these
files, processes them in some way, and saves them again, and then the
Gambas program will read them in again.
 
I have no idea if this is a good method - either from the viewpoint of
development ease, or run-time efficiency. I can think of many
alternative ways to structure this task, which may or may not be better
- without knowing details of the task, or why you might prefer a
particular setup.
 
But it does seem to me that you are making your decisions based on gut
feeling rather than research or measurement. That does not mean your
decisions are wrong, but it might mean you should not be so confident in
them.
 
 
>> /now/, rather than picking a bad structure from the start.
 
> please give your judgement about the struct I have described before,
> which drawbacks seems to have or don't have.
 
It sounds like it is probably fine - but as I have said before, you
haven't given all the important details clearly enough.
 
I want you to understand what is important when making such structures -
that everything is aligned properly (the best being "natural"
alignment), and I strongly recommend adding any padding manually as
unused "padding" fields. I want you to understand /why/ this is
important. And once you understand that, you will realise that "pragma
pack" and similar extensions are useless here and not only are you able
to avoid them, but you /should/ avoid them.
 
 
> oh I completely disagree with this point ! The format has to be packed
> as the C++ library receives the file from an other source of data that
> offers them in that form, so it's mandatory.
 
No, it is not. Not remotely. It would be a sad state for C and C++ if
they required compiler-specific extensions to deal with data from
external sources.
 
I think perhaps you are mixing up the concepts of "a structure where the
fields are adjacent with no padding" and "uses pragma packed". I am
recommending using structs fit the former, without ever using the later.
 
Or perhaps you think compilers add random padding and re-arrange structs
in odd and unpredictable ways. The details here are usually specified
by the platform's ABI, precisely so that programs can exchange data
safely (by files, pipes, streams, shared memory, shared libraries, etc.).
 
 
> nope, I have constraints to fullfil. Maybe inefficient, maybe non
> portable (who cares ?), but surely not pointless, as otherwise data
> exchange would not work at all
 
"pragma pack" is pointless here.
 
Paavo Helde <myfirstname@osa.pri.ee>: Nov 23 02:51PM +0200

On 23.11.2019 12:12, Soviet_Mario wrote:
> when avoiding specific Q-prefixes.
 
> so, HERE, including
> #include <sys/types.h>
 
<sys/types.h> belongs to The Open Group which is "the certifying body
for the UNIX trademark". It has nothing to do with QT and neither with
standard C++. Also, it appears the u_int8_t typedef is not documented,
meaning that it is an implementation detail which you can't rely on. For
example, in Windows there is a <sys/types.h> header, but it does not
define u_int8_t.
 
So why cannot you listen to everybody here who are trying to give you
good advice, and use <cstdint> and std::uint8_t?
Soviet_Mario <SovietMario@CCCP.MIR>: Nov 25 12:44PM +0100

On 24/11/2019 22:46, Öö Tiib wrote:
 
> So removal of inline from non-template function when it is included
> from multiple translation units leads to ODR violation and undefined
> behavior.
 
uhm ... I must admit I did not understand most.
 
> There are no inline linkage.
 
in general or in this case ?
 
> Functions declared inline (or constexpr
> that is implicitly inline) have external linkage by default.
> The sole "benefit" we are guaranteed to get from inline
is that we
> may include same header that defines the inline function
in multiple
> translation units without violating ODR.
 
I'm not sure : then Inline seems to grant the possibility of
"redefinition" without redefining (as it is not considered a
real function) ? Right ?
 
I tend to embed some very short function in headers instead
of a "pure" interface description and put ALL code in the
.CPP unit. Is it a bad practice ?
 
In case it is not a so bad habit :
* I ought to add inline in all functions in the headers ?
* It is a "must" only if I wish to include the same headers
multiple times in different .CPP units ? (to avoid the
redeclaration) ?
* in headers I actually put "safeguard" like
 
#ifndef THIS_HEADER
#define THIS_HEADER
.....
.....
.....

No comments: