Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #69728
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Newsgroups | comp.lang.c++ |
| Subject | Re: [QT creator on "nix"] - getting a strict 8 bit (1 byte) array with no padding |
| Date | 2019-11-24 20:53 +0100 |
| Organization | A noiseless patient Spider |
| Message-ID | <qren31$fs3$1@dont-email.me> (permalink) |
| References | (7 earlier) <qr8deq$tm2$1@dont-email.me> <qr8gep$esf$1@dont-email.me> <qr8jeg$v7n$1@dont-email.me> <qr8pu5$657$1@dont-email.me> <qr99qg$ats$1@dont-email.me> |
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>
> put is alas irregular verb : I meant its PAST form actually.
> I have abandoned the unsigned Bit_Field : 8 solution as soon as you (a
> lot of people) stated that u_int_8 MUST have exactly 8 bits.
>
> 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.
>
>> If you don't know what you are doing
>
> I'm rather weak in higher level C++ constructs, and I know that, but not
> particularly so in low level (some couple of tens of years ago I used to
> stuff C code with inline "asm" statements or even __emit() calls).
>
>> , fine - if I understand you
>> correctly, you are experienced with gambas
>
> no, I am rather new to gambas actually.
> I was used to VB (Visual Studio, but not even recently). Going to Gambas
> has been actually a pain (not saying it is bad, absolutely not : it's me
> that knows much less than .net framework). On QT I am even more newby.
>
>> programming but new to C++.
>
> well, I am more of outdated than new, I had used C++ (and C) a lot in
> 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.
>
>> And when the more experienced
>> 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.
>
> Anyway, there are three scenarios
>
> 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.
> either
> 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.
>
> as for ALIGNMENT problem, I should not meet any I guess.
> 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.
>
>
>> then that is what you should do. Ask /why/, and try to learn
>> - and once you do understand "pack", when it can be useful, when it is
>> 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.
>
>> what it does, and what it costs
>> - /then/ you can decide that because you know the full situation better
>> than we do, you still want to use it against general advice.
>
> I had given all details sufficient : the data layout is what I said, so
> no obscure aspects
>
>>
>> "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".
> I was not saying it would be successful necessarily in every
> scenario (even sizes sequence is relevant, and I know this, but my
> members were all 1 byte long)
>
>> it is a last choice solution when you
>> have nothing better and know you can't write the code as well without
>> it. (That might mean you can't write the code as quickly or clearly
>> without it, which is fair enough - /if/ you are sure it is necessary.)
>
> let's say it explicitely
>
> if I have
> union
> {
> struct
> {
> u_int_8 Red, Green, Blue, Alpha;
> };
> u_int_32 AllChannels;
> };
>
> 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.
> At worsk it would be
> insufficient to actually pack it, so my problem is unsolved.
> 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>
>> And if your file format contains non-aligned members,
>
> why making general guess when I reported precisely the layout ?
> 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.
> In the ram layout,
> the BMP descriptor has width and height as "local" members, and a
> pointer to an array of struct aligned in memory by the NEW [] operator
> who is aware of alignment requirements.
>
> Where are the possible problems ?
> What problems are affected by a pragma pack directive ?
>
>
>> then the simplest
>> and easiest way to improve and simplify the code, and improve the speed
>> of several parts, is to fix the file format.
>
> that point is unmodificable. I strictly need full color and no
> compression. The alpha channel is maybe a bit overkill (255 level of
> 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.
>
>> Make sure the members are
>> aligned (add explicit dummy members if necessary)
>
> since when reading/writing files suffer from this ? Files are BYTE
> 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.
>
> as for memory : I instance the BMP array invoking
> ptrBMP = new clsMyStructColor [TotSize];
> and I expect the structs are aligned correctly as NEW knows its task.
>
>> - then forget you ever
>> heard of "pragma pack".
>>
>>>
>>>
>>>> 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)
>>
>> No one can tell you if it is the same without knowing the file format.
>
>
> I just said it : the stupidest format of all
>
> 16 bit (width) - 16 bit (height) - N x 32 bit (R,G,B,alpha)
> where N = width x height = number of "pixels"
>
>
>>
>> There is nothing wrong with having the ram and disk layout the same -
>
> oh happy to know ! :)
>
>> often that is a very convenient and efficient choice. But if the disk
>> layout is not directly usable in ram, then it often is /not/ a
>> convenient and efficient choice - and if it /is/ usable directly in ram,
>> you don't need or want "pack".
>
> I was asking about the specific case
>
>>
>> However you look at it, "pack" is usually (but not always) the wrong
>> choice. You should only consider it once you have eliminated better
>> 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.
>
>>
>> As for asking for help here, you are getting the help you need even if
>> it is not exactly what you asked for.
>
> not a problem, every advice is appreciated
>
>> It's as though you said "I need a
>> new toothbrush. Can you tell me how to get to the toy shop?" It is
>> conceivable that a toy shop might have toothbrushes, but it is very
>> unlikely to be a good choice. Would you not rather have people say "You
>> don't want to go to a toy shop. You want to go to a chemist - this is
>> how you get there" ?
>>
>>>
>>>> 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
>>>
>>
>> First, you take a step back. You look to see if the packed file really
>> is "packed",
>
> 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.
>
>> in the sense of having unaligned data that would have
>> 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.
>
>>
>> If the format is already good, you are done. One memcpy, or read from
>> the file directly to a suitable buffer, or memmap to the file directly
>> (no reading or writing needed).
>
> memmap is a problem in that I don't know how exactly works and whether
> or not I'll be able to interoperate with memory files opened in gambas
>
> I am also considering to use some memory files supported directly by the
> OS (here on linux files created on /shm virtual folder are designed for
> 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.
>
>> This would be good for all parts of the system. When the format is
>> changed, you are done. Again, I have had no answer to whether this is
>> possible.
>>
>> If the format is bad, and cannot be fixed, then you have to write reader
>> and writer functions that unpack and pack the data into the right
>> 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.
>
>> reasons - you already have something to handle starting with the file
>> header and then allocating memory depending on the size. It is very
>> normal to have a function that reads in the data format and uses it to
>> populate an internal format.
>
> in fact, minimally, I do this. First create the container, with just a
> couple of members, then depending on their value, size the buffer and
> allocate it, then load the file in it.
>
>> Perhaps your file format uses 8-bit
>> unsigned data for colour channels, but your internal format uses
>> floating point because that suits your processing needs.
>
> On certain routines I use floating point, but only temporarily, as I
> never STORE floating point pixels. I don't need a huge precision, as
> operations are not supposed to be applied multiple times on the same
> picture, creating rounding additive errors.
>
>> Perhaps the
>> file format uses run-length encoding for smaller files, and you want to
>> expand it to a raw array. There are all sorts of things that go on in
>> typical reader functions. Making them a "single operation", whatever
>> that might mean,
>
> sth encoded in a single call to fread / fwrite, at least for the pixel
> data block. The header is distinct
>
>> is rarely relevant - code that uses these functions has
>> a "single operation" of calling the reader function.
>
> well, fread/fwrite may maybe internally operate differently than
> expected, but in this case I would not be able to do better I guess :)
>
>
>>
>>
>>>>
>>>> (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
>>
>> Perhaps - but not necessarily the ones you think are irrelevant. IMHO,
>> of course.
>>
>> (And to be clear - I did not right this to be rude, or insulting, or
>> demoralising, and I hope it did not come across that way.
>
> no problem, really
>
>> I am writing
>> to push you to think about things that are important here, but which I
>> feel you are skipping. The aim is that you learn more, and that you can
>> write better code that is clear, correct and efficient without wasting
>> effort on poorer techniques.)
>>
>>>
>>>>
>>>>
>>>> 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.
>>
>> Doing this all "in one single shot" should not be an aim. Doing it in a
>
> I wish to both get fast disk I/O but also limit the try/catch trapping.
> I have the habit to catch or check errno on every disk access. A single
> huge read/write makes the code thinner than splitting the accesses in
> many place and having to multiplicate the error condition testing.
>
>> way that makes the code simple and clear, easy to develop, easy to read
>> and easily correct should be your aim. Quite possibly your real goal
>> would be easiest achieved by using a standard format (like PNG) and
>> existing libraries for gambas and C++. Call the one function - simple
>> and clear.
>>
>>> And have a RAM layout simple enough not to require bitwise masking to
>>> locate fields (the drawback of a pure "bit fields" solution)
>>>
>>
>> Why would you want to bring bitfields into this?
>>
>>>> - I'll believe that, and it is
>>>> a perfectly good reason for using it. But if you try to tell me you
>>>> are
>>>> 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.
>>>
>>
>> Fair enough. So get it /right/ by designing the right data structure
>> /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.
>>
>>>>
>>>>>
>>>>>
>>>>> (*) well actually I do not make strictly a single load/save as stated.
>>>>> First I save/load a very small descriptor with WIDTH/HEIGHT stored
>>>>> as 16
>>>>> bit integers, then, aware of the array size of the buffer, alloc and
>>>>> fread or fwrite down.
>>>>>
>>>>> It's a very "stupid" non standard format, but I don't need to export
>>>>> 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 make it "naturally aligned". What will be the cost? A couple of
>> extra unsused padding bytes, added manually?
>>
>> struct pixel {
>> uint8_t red, green, blue, alpha;
>> };
>>
>> struct picture_format {
>> uint64_t key; // Always 0x0064727574636950ull
>> uint8_t file_type_version;
>> uint8_t padding1;
>> uint16_t height;
>> uint16_t width;
>> uint16_t padding2;
>>
>> pixel pixeldata[];
>> };
>>
>> Pick an alignment for the structure - 32-bit or 64-bit are good choices.
>> Start with a member of that size for convenience - I like a constant
>> marker to make it easy to tell that you are using the right file type.
>> (The value here is the string "Picture".)
>
> I have stripped everything non necessary as this raw format is only a
> temporary. When I actually store files, I export them as PNG of JPG or
> GIF by Gambas code.
> So my internal format was really minimal.
>
>> Make sure everything is
>> aligned sensibly. Add padding members manually and explicitly to keep
>> it clear - then there is never any doubt. (These may later be re-used
>> for extra information in later file format versions.) Make sure
>> separate blocks, such as the header and the data section, each are
>> aligned to the main large alignment for efficiency.
>>
>>>
>>> So I ask you, when I call NEW operator for an array of "pixel" structs,
>>> is it naturally aligned or not ?
>>
>> Yes, as long as you don't faff about with "packed" stuff. Then you
>> don't know.
>>
>>>
>>>
>>>> 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.
>>
>> Then it is inexcusable to have a format that needs "packed". That just
>
> 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.).
> And also the caller expects to get the transformed data back in the same
> packed form.
>
>> means totally pointless complications, inefficiencies, and non-portable
>> code.
>
> 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.
>
>>
>> If you have learned nothing else from this conversation, hopefully you
>> have learned that much.
>>
>>>
>>>> If the fields in the struct are not properly ("naturally")
>>>> aligned, change the format so that they are. That will help the gambas
>>>> side, help the C++ side, and mean you don't have to faff around with
>>>> "pack" extensions /or/ with extra packing and unpacking stages.
>>>>
>>>>
>>>
>>>
>>
>
>
Back to comp.lang.c++ | Previous | Next | Find similar | Unroll thread
Re: [QT creator on "nix"] - getting a strict 8 bit (1 byte) array with no padding David Brown <david.brown@hesbynett.no> - 2019-11-24 20:53 +0100
csiph-web