Discussion:
struct padding question
(too old to reply)
MehdiAmini
2017-03-23 09:58:23 UTC
Permalink
Raw Message
// struct padding question

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

#define N 6

static struct data
{ uint64_t ctr[N];
long double mean;
long double variance;
long double * probability_ptr;

} my_data;

void init_data( struct data* const);

int main(void)
{
init_data(&my_data);

return EXIT_SUCCESS;
}

void init_data(struct data * const data_ptr)
{
data_ptr->probability_ptr = NULL;
for(long i = 0; i<N; i++)
data_ptr->ctr[i] = 0;
data_ptr->mean = (long double)0.0;
data_ptr->variance = (long double)0.0;

return;
}

// Compiling the above code I get the warning, how to fix it?

clang -pedantic -Weverything -Wall -m64 -std=c11

warning: padding size of 'struct data' with 8 bytes to alignment
boundary [-Wpadded]
static struct data
^
--
Farewell.
David Brown
2017-03-23 10:28:12 UTC
Permalink
Raw Message
Post by MehdiAmini
// struct padding question
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#define N 6
static struct data
{ uint64_t ctr[N];
long double mean;
long double variance;
long double * probability_ptr;
} my_data;
void init_data( struct data* const);
int main(void)
{
init_data(&my_data);
return EXIT_SUCCESS;
}
void init_data(struct data * const data_ptr)
{
data_ptr->probability_ptr = NULL;
for(long i = 0; i<N; i++)
data_ptr->ctr[i] = 0;
data_ptr->mean = (long double)0.0;
data_ptr->variance = (long double)0.0;
return;
}
// Compiling the above code I get the warning, how to fix it?
clang -pedantic -Weverything -Wall -m64 -std=c11
warning: padding size of 'struct data' with 8 bytes to alignment
boundary [-Wpadded]
static struct data
^
When you define a struct in C, the compiler may add extra "padding"
bytes in order to make sure all the alignments are correct for the
struct members. It may also add padding at the end of the struct, so
that alignments would be correct in an array of the structs.

This is normal C behaviour. But sometimes, people don't want to waste
this space, or they may have expected their struct to fit accurately so
that padding indicates a mistake in their code. Thus some compilers
(gcc and clang, certainly, but maybe many others) can warn if they add
padding. This is controlled by the "-Wpadded" or "-Wno-padded" flags.
Normally, this warning is disabled - gcc does not include it in "-Wall
-Wextra". Apparently, clang has it in "-Weverything".

You may decide that this warning is not a problem - for most code,
padding bytes are not an issue. Then you simply add "-Wno-padded" to
your compiler line. This does not change your code, but it hides the
warning.

Alternatively, you need to re-arrange your struct so that there are no
paddings needed.

The struct you have now is:

struct data {
uint64_t ctr[6]; // 8-byte alignment, 8x6 data
long double mean; // 16-byte alignment, 16-byte data
long double variance; // 16-byte alignment, 16-byte data
long double * p_ptr; // 8-byte alignment, 8-byte data

// inserted by compiler...
uint64_t padding; // 8-byte alignment, 8-byte data
};

This final hidden padding is added to make the whole struct a multiple
of 16 bytes. If you add it explicitly, you will get the same structure
in your code and no warning.

Note that such alignments and paddings are implementation-dependent - on
an implementation with 8-byte "long double", or a platform with an 8
byte (or less) maximum alignment, there would be no padding here.
MehdiAmini
2017-03-23 12:14:32 UTC
Permalink
Raw Message
[...]
Post by David Brown
You may decide that this warning is not a problem - for most code,
padding bytes are not an issue. Then you simply add "-Wno-padded" to
your compiler line. This does not change your code, but it hides the
warning.
Alternatively, you need to re-arrange your struct so that there are no
paddings needed.
[...]

Can I use alignas or alignof to fix the warning?
--
Farewell.
j***@gmail.com
2017-03-23 12:30:08 UTC
Permalink
Raw Message
Post by MehdiAmini
[...]
Post by David Brown
You may decide that this warning is not a problem - for most code,
padding bytes are not an issue. Then you simply add "-Wno-padded" to
your compiler line. This does not change your code, but it hides the
warning.
Alternatively, you need to re-arrange your struct so that there are no
paddings needed.
[...]
Can I use alignas or alignof to fix the warning?
No: you can't use alignas to weaken the alignment requirement.

The issue here is that your struct has a natural size which is not a multiple of its alignment and that C demands that the size of a struct is a multiple of its alignment, thus padding is added to increase the size of the struct to the next multiple of its alignment.

You can not "fix" that without modifying the struct, and any fix will have the same effect than what is done automatically, excepted that it would be counterproductive on some platform (for instance, one were long double has a alignment of 8 -- perhaps because it is not represented differently than double).


Insisting to both have every potential warnings active and compile with no warning is usually unwise. There are some warnings which are there just for periodic review or when issue hunting -- like this one -- or even for special circumstances -- gcc had, perhaps still have, warnings to help porting from K&R C to standard C; activating and fixing those for a program written in standard C makes usually no sense.

Yours,
--
Jean-Marc
Keith Thompson
2017-03-23 15:45:33 UTC
Permalink
Raw Message
Post by MehdiAmini
[...]
Post by David Brown
You may decide that this warning is not a problem - for most code,
padding bytes are not an issue. Then you simply add "-Wno-padded" to
your compiler line. This does not change your code, but it hides the
warning.
Alternatively, you need to re-arrange your struct so that there are no
paddings needed.
[...]
Can I use alignas or alignof to fix the warning?
Exactly what problem are you trying to solve?

The simplest way to avoid the warning is to add "-Wno-padded" to
your compiler command line. If you want the structure not to have
padding, that's a more complicated question. In some cases you can
rearrange the member declarations, but in this case you could add
a dummy member to occupy the space that would otherwise be padding.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Noob
2017-04-01 17:15:25 UTC
Permalink
Raw Message
Post by David Brown
struct data {
uint64_t ctr[6]; // 8-byte alignment, 8x6 data
long double mean; // 16-byte alignment, 16-byte data
long double variance; // 16-byte alignment, 16-byte data
long double * p_ptr; // 8-byte alignment, 8-byte data
// inserted by compiler...
uint64_t padding; // 8-byte alignment, 8-byte data
};
I think some platforms have sizeof(long double) = 10?
(I have x86 in mind, with the 80-bit FP numbers.)

Regards.
tim prince
2017-04-01 18:41:38 UTC
Permalink
Raw Message
Post by Noob
Post by David Brown
struct data {
uint64_t ctr[6]; // 8-byte alignment, 8x6 data
long double mean; // 16-byte alignment, 16-byte data
long double variance; // 16-byte alignment, 16-byte data
long double * p_ptr; // 8-byte alignment, 8-byte data
// inserted by compiler...
uint64_t padding; // 8-byte alignment, 8-byte data
};
I think some platforms have sizeof(long double) = 10?
(I have x86 in mind, with the 80-bit FP numbers.)
No, compilers which follow the precedent of gcc store 80-bit long double
aligned to 12 bytes for x86 32-bit and 16 bytes for x86_64 64-bit (as
Intel used to recommend before they began recommending not using that
data type). So it's non-portable to make assumptions about this.
--
Tim Prince
s***@casperkitty.com
2017-04-02 16:15:04 UTC
Permalink
Raw Message
Post by tim prince
No, compilers which follow the precedent of gcc store 80-bit long double
aligned to 12 bytes for x86 32-bit and 16 bytes for x86_64 64-bit (as
Intel used to recommend before they began recommending not using that
data type). So it's non-portable to make assumptions about this.
Why wouldn't the optimal alignment be 16 bits on any system with a 64-bit or
smaller bus? Unless the bus size gets to be larger than 64 bits, every load
is either going to precisely fill some number of words (8-bit or 16-bit bus)
or else is going to be whole number of words plus an extra 16-bit chunk (the
larger bus case). Only in the 128-bit bus case would alignment matter, and
in that case the optimal alignment wouldn't depend upon whether the CPU was
in 32-bit or 64-bit mode.
Scott Lurndal
2017-04-03 13:51:54 UTC
Permalink
Raw Message
Post by s***@casperkitty.com
Post by tim prince
No, compilers which follow the precedent of gcc store 80-bit long double
aligned to 12 bytes for x86 32-bit and 16 bytes for x86_64 64-bit (as
Intel used to recommend before they began recommending not using that
data type). So it's non-portable to make assumptions about this.
Why wouldn't the optimal alignment be 16 bits on any system with a 64-bit or
smaller bus?
Bus? What bus? FWIW, the last three generations of Intel processors
and several other high-end RISC server processors have multiple
bi-directional 512-bit-wide (or more) rings connecting
the cores to each other (and the on-chip memory controllers) sufficient
to transfer entire cache lines from LLC to per-core caches in a single
clock.

Other processors use non-blocking crossbar switches.

The front-side-bus is dead, jim.
Post by s***@casperkitty.com
Unless the bus size gets to be larger than 64 bits, every load
is either going to precisely fill some number of words (8-bit or 16-bit bus)
or else is going to be whole number of words plus an extra 16-bit chunk (the
larger bus case). Only in the 128-bit bus case would alignment matter, and
in that case the optimal alignment wouldn't depend upon whether the CPU was
in 32-bit or 64-bit mode.
s***@casperkitty.com
2017-04-03 14:48:41 UTC
Permalink
Raw Message
Post by Scott Lurndal
Post by s***@casperkitty.com
Why wouldn't the optimal alignment be 16 bits on any system with a 64-bit or
smaller bus?
Bus? What bus? FWIW, the last three generations of Intel processors
and several other high-end RISC server processors have multiple
bi-directional 512-bit-wide (or more) rings connecting
the cores to each other (and the on-chip memory controllers) sufficient
to transfer entire cache lines from LLC to per-core caches in a single
clock.
Nowadays processors have very wide on-chip buses that connect to cache, and
only slightly-less-wide buses that connect to main memory, but it was not
always thus.
Post by Scott Lurndal
Other processors use non-blocking crossbar switches.
The front-side-bus is dead, jim.
I'm curious on what systems there would have been an advantage to having
32-bit alignment but not 128-bit alignment. If objects are randomly aligned
at 64-bit boundaries and cache lines are 128N bits, then 1/(2N-1) objects
will span a cache-line boundary. If objects were randomly aligned at 32-bit
boundaries, the fraction would be the same, and likewise if they are aligned
at 16-bit boundaries. It may be that Intel decided not to support efficient
80-bit fetches with all 16-bit alignments, but there is no inherent reason
that objects of that size should need to be less efficient with 16-bit
alignment than with coarser alignment.
Scott Lurndal
2017-04-03 15:47:22 UTC
Permalink
Raw Message
Post by s***@casperkitty.com
Post by Scott Lurndal
Post by s***@casperkitty.com
Why wouldn't the optimal alignment be 16 bits on any system with a 64-bit or
smaller bus?
Bus? What bus? FWIW, the last three generations of Intel processors
and several other high-end RISC server processors have multiple
bi-directional 512-bit-wide (or more) rings connecting
the cores to each other (and the on-chip memory controllers) sufficient
to transfer entire cache lines from LLC to per-core caches in a single
clock.
Nowadays processors have very wide on-chip buses that connect to cache, and
only slightly-less-wide buses that connect to main memory, but it was not
always thus.
For which we have NTTP://alt.computers.folklore.
Post by s***@casperkitty.com
Post by Scott Lurndal
Other processors use non-blocking crossbar switches.
The front-side-bus is dead, jim.
I'm curious on what systems there would have been an advantage to having
32-bit alignment but not 128-bit alignment.
Struct alignment, for example has two important characteristics:

1) Field alignment on natural boundaries (for optimal access)
2) Total size alignment on appropriate boundaries for correctness
when accessing fields in arrays of objects.

Take ARMv8 (64-bit) for instance. The stack pointer must always
be 16-byte aligned (the hardware will fault any operation that would
result in a non-16-byte aligned stack pointer).
Post by s***@casperkitty.com
If objects are randomly aligned
at 64-bit boundaries and cache lines are 128N bits, then 1/(2N-1) objects
will span a cache-line boundary. If objects were randomly aligned at 32-bit
boundaries, the fraction would be the same, and likewise if they are aligned
at 16-bit boundaries. It may be that Intel decided not to support efficient
80-bit fetches with all 16-bit alignments, but there is no inherent reason
that objects of that size should need to be less efficient with 16-bit
alignment than with coarser alignment.
Consider pushing one of those 10-byte floats on the stack... Almost every stack
access thereafter will be unaligned, and thus performance will suffer
(assuming the AF flag isn't set).

Even _within_ a cache line, unaligned accesses have a performance penalty.
s***@casperkitty.com
2017-04-03 16:24:06 UTC
Permalink
Raw Message
Post by Scott Lurndal
Post by s***@casperkitty.com
Nowadays processors have very wide on-chip buses that connect to cache, and
only slightly-less-wide buses that connect to main memory, but it was not
always thus.
For which we have NTTP://alt.computers.folklore.
You were saying bus width is an antiquated consideration. So which are
you calling folklore--the idea that it's no longer a consideration (an
idea you were just promoting) or the idea that it ever was (which can be
confirmed by examining data sheets of older processors)?
Post by Scott Lurndal
Post by s***@casperkitty.com
I'm curious on what systems there would have been an advantage to having
32-bit alignment but not 128-bit alignment.
Take ARMv8 (64-bit) for instance. The stack pointer must always
be 16-byte aligned (the hardware will fault any operation that would
result in a non-16-byte aligned stack pointer).
Many systems have required that the stack pointer have an alignment
coarser than the size of objects placed upon it. The Motorola 68000, for
example, had instructions to push and pop 16-bit values from the stack,
but such instructions would adjust the stack pointer by 4 rather than by
2, so as to maintain 32-bit alignment. On family members with a 16-bit
data bus, pushing or popping a 16-bit value would save four cycles versus
a 32-bit value, but keeping the stack aligned would ensure good performance
on the later family members with a 32-bit bus.
Post by Scott Lurndal
Post by s***@casperkitty.com
If objects are randomly aligned
at 64-bit boundaries and cache lines are 128N bits, then 1/(2N-1) objects
will span a cache-line boundary. If objects were randomly aligned at 32-bit
boundaries, the fraction would be the same, and likewise if they are aligned
at 16-bit boundaries. It may be that Intel decided not to support efficient
80-bit fetches with all 16-bit alignments, but there is no inherent reason
that objects of that size should need to be less efficient with 16-bit
alignment than with coarser alignment.
Consider pushing one of those 10-byte floats on the stack... Almost every stack
access thereafter will be unaligned, and thus performance will suffer
(assuming the AF flag isn't set).
So pad the items when pushing to the stack. Nothing in the C Standard says
that objects placed on the stack need to have the same padding as those
placed elsewhere. The 32-bit ARM ABI, for example, seems to call for 64-bit
values to be 64-bit aligned on the stack, even though elsewhere in memory
such values are often only 32-bit aligned.
Post by Scott Lurndal
Even _within_ a cache line, unaligned accesses have a performance penalty.
If cache lines are divided into power-of-two-size pieces which can be
accessed in whole or in part, the number of accesses required to load or
store an 80-bit value would be independent of bits 1-2 of the address.
Whether a processor includes the circuitry needed to handle shifts of
arbitrary alignment would be another question, though such circuitry would
be advantageous in enough other situations (e.g. a bulk memory copy between
differently-aligned regions) that I would think it worthwhile to include.
Keith Thompson
2017-04-01 18:43:42 UTC
Permalink
Raw Message
Post by Noob
Post by David Brown
struct data {
uint64_t ctr[6]; // 8-byte alignment, 8x6 data
long double mean; // 16-byte alignment, 16-byte data
long double variance; // 16-byte alignment, 16-byte data
long double * p_ptr; // 8-byte alignment, 8-byte data
// inserted by compiler...
uint64_t padding; // 8-byte alignment, 8-byte data
};
I think some platforms have sizeof(long double) = 10?
(I have x86 in mind, with the 80-bit FP numbers.)
The only values for sizeof (long double) I've seen are 8, 12, and 16.
Some implementations might pad a 10-byte long double to 12 bytes.
(Of course I haven't seen all implementations.)
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Robert Wessel
2017-04-01 18:46:00 UTC
Permalink
Raw Message
Post by Noob
Post by David Brown
struct data {
uint64_t ctr[6]; // 8-byte alignment, 8x6 data
long double mean; // 16-byte alignment, 16-byte data
long double variance; // 16-byte alignment, 16-byte data
long double * p_ptr; // 8-byte alignment, 8-byte data
// inserted by compiler...
uint64_t padding; // 8-byte alignment, 8-byte data
};
I think some platforms have sizeof(long double) = 10?
(I have x86 in mind, with the 80-bit FP numbers.)
There have been implementations of, 10-byte (80-bit), x86 long double
which have 2, 4, 8 and 16 byte alignment requirements.

For example, amongst compilers actually supporting the 80-bit type, MS
and Borland's 16-bit compilers use 2-byte alignment, several 32-bit
(typical x86 GCC, for example) compilers use 4B alignment, Watcom uses
8B in both 16 and 32-bit versions, and most *nix compilers on 64B use
16B alignment, as does ICC on Windows in both 32 and 64B modes).

*Not* intended to be an exhaustive list.
Keith Thompson
2017-04-01 19:00:00 UTC
Permalink
Raw Message
Robert Wessel <***@yahoo.com> writes:
[...]
Post by Robert Wessel
There have been implementations of, 10-byte (80-bit), x86 long double
which have 2, 4, 8 and 16 byte alignment requirements.
For example, amongst compilers actually supporting the 80-bit type, MS
and Borland's 16-bit compilers use 2-byte alignment, several 32-bit
(typical x86 GCC, for example) compilers use 4B alignment, Watcom uses
8B in both 16 and 32-bit versions, and most *nix compilers on 64B use
16B alignment, as does ICC on Windows in both 32 and 64B modes).
*Not* intended to be an exhaustive list.
The size of a type must be a whole multiple of its alignment; arrays
cannot have gaps between elements. If a 10-byte floating-point type
requires 4-byte alignment, it must be padded to at least 12 bytes.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Robert Wessel
2017-04-01 21:40:23 UTC
Permalink
Raw Message
Post by Keith Thompson
[...]
Post by Robert Wessel
There have been implementations of, 10-byte (80-bit), x86 long double
which have 2, 4, 8 and 16 byte alignment requirements.
For example, amongst compilers actually supporting the 80-bit type, MS
and Borland's 16-bit compilers use 2-byte alignment, several 32-bit
(typical x86 GCC, for example) compilers use 4B alignment, Watcom uses
8B in both 16 and 32-bit versions, and most *nix compilers on 64B use
16B alignment, as does ICC on Windows in both 32 and 64B modes).
*Not* intended to be an exhaustive list.
The size of a type must be a whole multiple of its alignment; arrays
cannot have gaps between elements. If a 10-byte floating-point type
requires 4-byte alignment, it must be padded to at least 12 bytes.
That's true, but MS/Borland long doubles on their 16-bit compilers had
a size of 10 bytes (and 2B alignment).
Keith Thompson
2017-04-01 22:24:21 UTC
Permalink
Raw Message
Post by Robert Wessel
Post by Keith Thompson
[...]
Post by Robert Wessel
There have been implementations of, 10-byte (80-bit), x86 long double
which have 2, 4, 8 and 16 byte alignment requirements.
For example, amongst compilers actually supporting the 80-bit type, MS
and Borland's 16-bit compilers use 2-byte alignment, several 32-bit
(typical x86 GCC, for example) compilers use 4B alignment, Watcom uses
8B in both 16 and 32-bit versions, and most *nix compilers on 64B use
16B alignment, as does ICC on Windows in both 32 and 64B modes).
*Not* intended to be an exhaustive list.
The size of a type must be a whole multiple of its alignment; arrays
cannot have gaps between elements. If a 10-byte floating-point type
requires 4-byte alignment, it must be padded to at least 12 bytes.
That's true, but MS/Borland long doubles on their 16-bit compilers had
a size of 10 bytes (and 2B alignment).
Which is consistent with what I said. But you also said that
a 10-byte long double could have a 4, 8, or 16 byte alignment,
which is not possible.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Robert Wessel
2017-04-03 22:46:47 UTC
Permalink
Raw Message
Post by Keith Thompson
Post by Robert Wessel
Post by Keith Thompson
[...]
Post by Robert Wessel
There have been implementations of, 10-byte (80-bit), x86 long double
which have 2, 4, 8 and 16 byte alignment requirements.
For example, amongst compilers actually supporting the 80-bit type, MS
and Borland's 16-bit compilers use 2-byte alignment, several 32-bit
(typical x86 GCC, for example) compilers use 4B alignment, Watcom uses
8B in both 16 and 32-bit versions, and most *nix compilers on 64B use
16B alignment, as does ICC on Windows in both 32 and 64B modes).
*Not* intended to be an exhaustive list.
The size of a type must be a whole multiple of its alignment; arrays
cannot have gaps between elements. If a 10-byte floating-point type
requires 4-byte alignment, it must be padded to at least 12 bytes.
That's true, but MS/Borland long doubles on their 16-bit compilers had
a size of 10 bytes (and 2B alignment).
Which is consistent with what I said. But you also said that
a 10-byte long double could have a 4, 8, or 16 byte alignment,
which is not possible.
What I (unclearly) meant, was that the x86 80-bit temp-reals
implemented by various compilers as long doubles, had those alignment
requirements, but ignoring the pad bits.

BartC
2017-03-23 11:50:07 UTC
Permalink
Raw Message
Post by MehdiAmini
static struct data
{ uint64_t ctr[N];
long double mean;
long double variance;
long double * probability_ptr;
} my_data;
// Compiling the above code I get the warning, how to fix it?
clang -pedantic -Weverything -Wall -m64 -std=c11
warning: padding size of 'struct data' with 8 bytes to alignment
boundary [-Wpadded]
static struct data
Well, you did ask for 'everything', and the compiler took you literally.

Here, the message shouldn't really be a warning, but a 'note', which is
just advisory information. There's nothing actually wrong.

A warning would have been justified if the struct /wasn't/ padded, when
it was necessary.
--
bartc
David Brown
2017-03-23 13:08:46 UTC
Permalink
Raw Message
Post by BartC
Post by MehdiAmini
static struct data
{ uint64_t ctr[N];
long double mean;
long double variance;
long double * probability_ptr;
} my_data;
// Compiling the above code I get the warning, how to fix it?
clang -pedantic -Weverything -Wall -m64 -std=c11
warning: padding size of 'struct data' with 8 bytes to alignment
boundary [-Wpadded]
static struct data
Well, you did ask for 'everything', and the compiler took you literally.
Here, the message shouldn't really be a warning, but a 'note', which is
just advisory information. There's nothing actually wrong.
The warning exists because for some people, and some code, padding
structs means there /is/ something wrong. That is why I use it in a lot
of my code. But in this case, as for most "normal PC" software, it is
not a problem.
Post by BartC
A warning would have been justified if the struct /wasn't/ padded, when
it was necessary.
That would be a warning along the lines of "internal compiler error -
something is broken in the compiler". ICE's are generally fatal, not
warnings, and they are not optional.
BartC
2017-03-23 13:31:40 UTC
Permalink
Raw Message
Post by David Brown
Post by BartC
A warning would have been justified if the struct /wasn't/ padded, when
it was necessary.
That would be a warning along the lines of "internal compiler error -
something is broken in the compiler".
There may be a '#pragma pack(1)' still in effect that the user wasn't
aware of (set inside an include file for example).
David Brown
2017-03-23 13:46:41 UTC
Permalink
Raw Message
Post by BartC
Post by David Brown
Post by BartC
A warning would have been justified if the struct /wasn't/ padded, when
it was necessary.
That would be a warning along the lines of "internal compiler error -
something is broken in the compiler".
There may be a '#pragma pack(1)' still in effect that the user wasn't
aware of (set inside an include file for example).
If that is the case, then the struct does not need padding - because you
have specifically told it /not/ to use padding. The compiler cannot
guess whether the user is or is not aware of things like a "#pragma
pack" directive - it has to assume that this is in effect because the
programmer wants it.
BartC
2017-03-23 14:07:57 UTC
Permalink
Raw Message
Post by David Brown
Post by BartC
There may be a '#pragma pack(1)' still in effect that the user wasn't
aware of (set inside an include file for example).
If that is the case, then the struct does not need padding - because you
have specifically told it /not/ to use padding.
You can use this argument about almost anything it warns about.

The compiler cannot
Post by David Brown
guess
That's right; it it can't guess.

whether the user is or is not aware of things like a "#pragma
Post by David Brown
pack" directive - it has to assume that this is in effect because the
programmer wants it.
'The' programmer? There could be several, including the one who used
pack(1) inside a header and forgot to reset it, and the one who uses
that header in good faith.

It would funny if the compiler gave a warning about struct padding which
does no harm, but doesn't do so about necessary padding being omitted.
--
bartc
David Brown
2017-03-23 14:52:06 UTC
Permalink
Raw Message
Post by BartC
Post by David Brown
Post by BartC
There may be a '#pragma pack(1)' still in effect that the user wasn't
aware of (set inside an include file for example).
If that is the case, then the struct does not need padding - because you
have specifically told it /not/ to use padding.
You can use this argument about almost anything it warns about.
That is why compilers typically make most warnings optional.

Warning collections, such as "-Wall" or "-Wextra", are just selections
that match many people's coding practices.
Post by BartC
The compiler cannot
Post by David Brown
guess
That's right; it it can't guess.
whether the user is or is not aware of things like a "#pragma
Post by David Brown
pack" directive - it has to assume that this is in effect because the
programmer wants it.
'The' programmer? There could be several, including the one who used
pack(1) inside a header and forgot to reset it, and the one who uses
that header in good faith.
That is an issue for development practices, not a matter for the
compiler to solve.
Post by BartC
It would funny if the compiler gave a warning about struct padding which
does no harm, but doesn't do so about necessary padding being omitted.
If the padding is /necessary/ for a given target, the compiler will not
omit it. It might be necessary for the logic of the program, but that
is up to the programmer, not the compiler.
Scott Lurndal
2017-03-23 17:19:49 UTC
Permalink
Raw Message
Post by David Brown
Post by BartC
It would funny if the compiler gave a warning about struct padding which
does no harm, but doesn't do so about necessary padding being omitted.
If the padding is /necessary/ for a given target, the compiler will not
omit it. It might be necessary for the logic of the program, but that
is up to the programmer, not the compiler.
The padding is generally /necessary/ for performance, not correctness,
as most modern architectures support unaligned accesses (albeit often
with a performance penalty). On those that don't support unaligned
accesses (e.g. intel with the AF flag set, or 32-bit arm), the padding
is necessary for correctness.

There are a few cases where packing is required for correctness, generally
to match some existing data structure or to interoperate with existing
applications.
David Brown
2017-03-23 18:57:56 UTC
Permalink
Raw Message
Post by Scott Lurndal
Post by David Brown
Post by BartC
It would funny if the compiler gave a warning about struct padding which
does no harm, but doesn't do so about necessary padding being omitted.
If the padding is /necessary/ for a given target, the compiler will not
omit it. It might be necessary for the logic of the program, but that
is up to the programmer, not the compiler.
The padding is generally /necessary/ for performance, not correctness,
as most modern architectures support unaligned accesses (albeit often
with a performance penalty). On those that don't support unaligned
accesses (e.g. intel with the AF flag set, or 32-bit arm), the padding
is necessary for correctness.
There are a few cases where packing is required for correctness, generally
to match some existing data structure or to interoperate with existing
applications.
Padding can be necessary for correctness for two reasons. One is to
avoid unaligned access (and I work with several different architectures
- there a number that don't support unaligned access). The other is
because your struct has to match an existing struct definition exactly,
such as a file structure, an filesystem structure, a network packet
format, or a set of hardware registers (which is the most common case
for my work). In these cases, the struct has to match precisely - with
as much or as little padding as necessary.
Ian Pilcher
2017-03-23 13:52:13 UTC
Permalink
Raw Message
Post by David Brown
The warning exists because for some people, and some code, padding
structs means there /is/ something wrong. That is why I use it in a lot
of my code. But in this case, as for most "normal PC" software, it is
not a problem.
Seems like _Static_assert is a better solution here than issuing a
warning every time the compiler adds padding to a structure.
--
========================================================================
Ian Pilcher ***@gmail.com
-------- "I grew up before Mark Zuckerberg invented friendship" --------
========================================================================
David Brown
2017-03-23 14:54:17 UTC
Permalink
Raw Message
Post by Ian Pilcher
Post by David Brown
The warning exists because for some people, and some code, padding
structs means there /is/ something wrong. That is why I use it in a lot
of my code. But in this case, as for most "normal PC" software, it is
not a problem.
Seems like _Static_assert is a better solution here than issuing a
warning every time the compiler adds padding to a structure.
I use both methods - "-Wpadded" can be convenient for a quick check in
cases where I know I want the struct to be packed tightly, and I use
static assertions (typically on the sizeof the struct) to make sure
sizes match the expected value for data that is transferred in or out of
the program.
s***@casperkitty.com
2017-03-23 15:29:12 UTC
Permalink
Raw Message
Post by David Brown
I use both methods - "-Wpadded" can be convenient for a quick check in
cases where I know I want the struct to be packed tightly, and I use
static assertions (typically on the sizeof the struct) to make sure
sizes match the expected value for data that is transferred in or out of
the program.
In some kinds of programming, structure types are used to achieve a storage
layout which is used elsewhere; being able to write something like:

someStruct->accessCount++;

rather than something like:

putU32le(&someStruct, ACCESS_COUNT_OFS,
getU32le(&someStruct, ACCESS_COUNT_OFS)+1);

is useful. Code which uses structures for purpose of creating bit-level
layouts can fail badly on compilers that don't process them as expected,
but that doesn't mean the technique *shouldn't* be supported in portable
fashion. The ability to use things like the former syntax is part of the
whole *point* of having a high-level language.

If there were a syntax to say whether a particular structure was
being used for data-overlay purposes, then compilers could squawk in cases
where it couldn't handle the intended layout of a data-overlay struct, but
not squawk if padding is added to a struct that isn't being used for such
a purpose.

I find it ironic that the .NET framework offers better support for such low-
level concepts than a language which was invented to facilitate low-level
programming.
GOTHIER Nathan
2017-03-23 13:04:13 UTC
Permalink
Raw Message
On Thu, 23 Mar 2017 14:28:23 +0430
Post by MehdiAmini
// struct padding question
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#define N 6
static struct data
{ uint64_t ctr[N];
long double mean;
long double variance;
long double * probability_ptr;
} my_data;
void init_data( struct data* const);
int main(void)
{
init_data(&my_data);
return EXIT_SUCCESS;
}
void init_data(struct data * const data_ptr)
{
data_ptr->probability_ptr = NULL;
for(long i = 0; i<N; i++)
data_ptr->ctr[i] = 0;
data_ptr->mean = (long double)0.0;
data_ptr->variance = (long double)0.0;
return;
}
// Compiling the above code I get the warning, how to fix it?
You should better use 64-bit aligned floats such as float or double rather than
the 80-bit aligned long double assuming your processor is AMD64 compatible. I
would recommend to use the long double type only for intermediate calculation
and not for aggregates such as arrays or structures.
MehdiAmini
2017-03-23 16:02:15 UTC
Permalink
Raw Message
Post by GOTHIER Nathan
On Thu, 23 Mar 2017 14:28:23 +0430
[...]
Post by GOTHIER Nathan
You should better use 64-bit aligned floats such as float or double rather than
the 80-bit aligned long double assuming your processor is AMD64 compatible. I
would recommend to use the long double type only for intermediate calculation
and not for aggregates such as arrays or structures.
using:
printf("%zu %zu\n",sizeof (long double),alignof(long double));

I get:
16 16

Not 80-bit.
--
Farewell.
GOTHIER Nathan
2017-03-23 17:35:21 UTC
Permalink
Raw Message
On Thu, 23 Mar 2017 20:32:15 +0430
Post by MehdiAmini
Post by GOTHIER Nathan
On Thu, 23 Mar 2017 14:28:23 +0430
[...]
Post by GOTHIER Nathan
You should better use 64-bit aligned floats such as float or double rather than
the 80-bit aligned long double assuming your processor is AMD64 compatible. I
would recommend to use the long double type only for intermediate calculation
and not for aggregates such as arrays or structures.
printf("%zu %zu\n",sizeof (long double),alignof(long double));
16 16
Not 80-bit.
https://en.wikipedia.org/wiki/Long_double

Indeed. The alignment depends on the implementation but anyway if your FPU
doesn't support more than 80-bits floats, you're wasting some memory space to
store the result in 128 bits to benefit of a correctly rounded 64-bit double.
s***@casperkitty.com
2017-03-23 19:02:22 UTC
Permalink
Raw Message
Post by MehdiAmini
Post by GOTHIER Nathan
You should better use 64-bit aligned floats such as float or double rather than
the 80-bit aligned long double assuming your processor is AMD64 compatible. I
would recommend to use the long double type only for intermediate calculation
and not for aggregates such as arrays or structures.
printf("%zu %zu\n",sizeof (long double),alignof(long double));
16 16
Not 80-bit.
The IEEE extended-precision format is essentially equivalent to:

struct IEEE_EXTENDED {
uint64_t mantissa;
uint16_t sign_and_exponent;
};

It has 80 bits of real data, but may be stored using 80, 96, or 128 bits
depending upon the required alignment for the mantissa.

On 16-bit or larger machines without floating-point units, working with
a 64-bit mantissa is no more expensive than working with a 53-bit mantissa,
and having the mantissa and exponent separated on a word boundary eliminates
the need to use bit shifting and bit masking operations when packing and
unpacking numbers. The existence of an extended type within IEEE-754 is a
good aspect of the design, but a couple aspects of how it's handled in C have
caused many people to unfairly view such a type as a mistake.

If C had specified that all computations on double promote to "long double"
[which might or might not be longer than double], all computations on float
promote to "long float" [whose precision could be anywhere between
that of "float" and "long double"], and all "normal" floating-point values
passed to variadic functions either promote to the same implementation-
defined type or to a type defined in the prototype, it would have been much
easier to write floating-point math code that works cleanly and efficiently
on many different implementations. Having long double passed to variadic
functions in a way incompatible with other floating-point types, though,
makes a lot of code needlessly dependent upon the types of floating-point
structure members and constants. Many compilers opted to avoid such
incompatibilities by using 80-bit types internally, but making "long double"
synonymous with "double"--a computational approach which reduces floating
point math to "hope for the best" semantics.
Keith Thompson
2017-03-23 19:21:48 UTC
Permalink
Raw Message
***@casperkitty.com writes:
[...]
Post by s***@casperkitty.com
If C had specified that all computations on double promote to "long double"
[which might or might not be longer than double], all computations on float
promote to "long float" [whose precision could be anywhere between
that of "float" and "long double"], and all "normal" floating-point values
passed to variadic functions either promote to the same implementation-
defined type or to a type defined in the prototype, it would have been much
easier to write floating-point math code that works cleanly and efficiently
on many different implementations.
Are you aware of the types float_t and double_t, both defined in
<math.h>, and the macro FLT_EVAL_METHOD, defined in <float.h>?
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
s***@casperkitty.com
2017-03-23 19:55:30 UTC
Permalink
Raw Message
Post by Keith Thompson
[...]
Post by s***@casperkitty.com
If C had specified that all computations on double promote to "long double"
[which might or might not be longer than double], all computations on float
promote to "long float" [whose precision could be anywhere between
that of "float" and "long double"], and all "normal" floating-point values
passed to variadic functions either promote to the same implementation-
defined type or to a type defined in the prototype, it would have been much
easier to write floating-point math code that works cleanly and efficiently
on many different implementations.
Are you aware of the types float_t and double_t, both defined in
<math.h>, and the macro FLT_EVAL_METHOD, defined in <float.h>?
I had been familiar with "FLT_EVAL_METHOD"; I'd not been familiar with
their relation to "float_t" and "double_t". The issue with variadic
functions is a bigger problem, though. It is so common to perform floating-
point computations within function arguments, and for such computations to
involve silent implicit conversions, that there is huge value in having a
compiler ensure that the results of any such computations get coerced into
the proper type for the called function. IMHO things would have been way
nicer if:

printf("%20.15f %20.15f", someDouble, someLongDouble);

would either pass both values as double, both as long double, or both as
some other implementation-defined type that was at least as accurate as
double while

printf("%20.15Lf", _WRAP_LONG_DOUBLE(anyFloatingPointExpr));

would pass the value as some implementation-defined type (possibly a
structure) containing all of the information required to hold the value
of a long double. In no case would the type of the floating-point value
or expression affect the required format specifier. Any non-wrapped
floating-point value would use %f, and any wrapped one would use %Lf.
Les Cargill
2017-03-25 20:12:08 UTC
Permalink
Raw Message
Post by MehdiAmini
// struct padding question
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#define N 6
static struct data
{ uint64_t ctr[N];
long double mean;
long double variance;
long double * probability_ptr;
} my_data;
void init_data( struct data* const);
int main(void)
{
init_data(&my_data);
return EXIT_SUCCESS;
}
void init_data(struct data * const data_ptr)
{
data_ptr->probability_ptr = NULL;
for(long i = 0; i<N; i++)
data_ptr->ctr[i] = 0;
data_ptr->mean = (long double)0.0;
data_ptr->variance = (long double)0.0;
return;
}
// Compiling the above code I get the warning, how to fix it?
clang -pedantic -Weverything -Wall -m64 -std=c11
warning: padding size of 'struct data' with 8 bytes to alignment
boundary [-Wpadded]
static struct data
^
Google for "pragma pack". Hopefully, you do not then encounter alignment
issues.
--
Les Cargill
TickleMe Elmo
2017-04-01 21:54:06 UTC
Permalink
Raw Message
Having to suffer the use of Fedora would just confuse the general user. How is Chrome on Linux doing anything above the lowest common denominator? Learn all about Jonas Eklundh AKA Sandman: <https://www.google.com/#q=Jonas+Eklundh+Sandman>. You guys can only think from the perspective of a sociopath. Spoken like a true Republican. Proof of the website skills of Sandman, Jonas Eklundh: <Loading Image...>. Kohlmann only thinks about Marek, Marek, Marek! That's right Marek! Are you being a stupid on purpose, Kohlmann?


This broke the Internet!

Jonas Eklundh Communication
Jonas Eklundh
2017-04-01 23:51:44 UTC
Permalink
Raw Message
Richard Stallman is a false advocate's hero.

My uptime is almost ninety-one days and them the facts, Jack! Marek is far too stupid to write a good script. The only scripting he's capable of doing is automating mouse clicks. Get out your Bingo cards and mark off a spot any time someone talks about the term "LCD" but uses a logical fallacy. Linux offers the least of any of the competition. You likely think Gnome handles the desktop well. Nope. Not compared to anything else, really. What is your evidence? My uptime is almost twenty-nine days and that is with doing a full update. I suspect you do not even know what is wrong with Marek. Another successful Ubuntu test. That is if you count the lowest common denominator of usage as a success. No reason to think the coders even care. This is something the mainstream media never covers.
--
What Every Entrepreneur Must Know!

Jonas Eklundh Communication AB
Jonas Eklundh
2017-04-02 00:15:21 UTC
Permalink
Raw Message
And in response you have nothing but an attempt to start a circus.

Marek's posts are nothing but an indecipherable mess. Bravo, Flatfish, you are now living rent-free inside Marek's beady little brain. Lul. Proof Sandman accuses everyone of being Snit Loading Image.... You have no idea how much a fool of yourself you are making. Don't look now, but I think Marek has a serious mancrush on Flatfish. You guys can only think from the perspective of a psychopath.

I still remain unconvinced that these posts are definitely automated.

RonB has yet to show how Kit Scenarist does anything above the LCD on Linux. What is your evidence? Marek's posts are nothing but an indecipherable mess. Cry harder Marek! LOL!

--
I Left My Husband & Daughter At Home And THIS happened

Jonas Eklundh
Jonas Eklundh
2017-04-02 11:50:27 UTC
Permalink
Raw Message
The herd's developed an AI system with (I am betting) value iteration to regurgitate texts which are in the form of ones from those of one particular legit member. Snit's posts are nothing but an indecipherable mess. You can say I am the Pope for all I care. Spoken like an MSM junkie. Usenet is a self-governing institution based on the honor system. Why does Snit focus on his own ego so much?

Do you think everyone who points out your trolling is evil? You have no idea how much a fool of yourself you are making. The herd members value the LCD in all things. "VM God" Marek shreds Snit in every way possible. Cry harder, Snit!

-
My Snoring Solution

Jonas Eklundh Communication
Steve Carroll
2017-04-03 19:17:59 UTC
Permalink
Raw Message
He is as incompetent as Marek. Proof of the website skills of Sandman, Jonas Eklundh: <http://tmp.gallopinginsanity.com/sandman/sandman-html-detail.pdf>. Proof of the website skills of Sandman, Jonas Eklundh: <http://tmp.gallopinginsanity.com/sandman/sandman_css_history.pdf>.

So Marek focuses on his ego. The herd does not complain.

Another successful "thumb drive install" test. That is if you count wasting time as a success. Sandman lies. Here is a list of names Jonas Eklundh has admitted he attributes to Snit "Cactus Pete", "Donald", "Donald Miller", "Horace McSwain", "Hymen", "Mike Weaver", "Modena IV Drid", "Omar Murad Asfour", "Rhino Plastee", "Soapy", "SopwithCamel", "Sunny Day", "Takuya Saitoh", "The Letter Q", "tmelmosfire", "zevon". My uptime is almost ninety-two days and that is with doing a full update. The herd members value conformity more than they do productivity. Richard Stallman is a false advocate's biggest fear. Time to blame the lack of many eyes!



--
Top Six Ways Snit Trolls!


Jonas Eklundh Communication AB
Loading...