Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #106789 > unrolled thread
| Started by | MehdiAmini <atorrses@gmail.com> |
|---|---|
| First post | 2017-03-23 14:28 +0430 |
| Last post | 2017-03-25 15:12 -0500 |
| Articles | 16 on this page of 36 — 13 participants |
Back to article view | Back to comp.lang.c
struct padding question MehdiAmini <atorrses@gmail.com> - 2017-03-23 14:28 +0430
Re: struct padding question David Brown <david.brown@hesbynett.no> - 2017-03-23 11:28 +0100
Re: struct padding question MehdiAmini <atorrses@gmail.com> - 2017-03-23 16:44 +0430
Re: struct padding question jm.bourguet@gmail.com - 2017-03-23 05:30 -0700
Re: struct padding question Keith Thompson <kst-u@mib.org> - 2017-03-23 08:45 -0700
Re: struct padding question Noob <root@127.0.0.1> - 2017-04-01 19:15 +0200
Re: struct padding question tim prince <n8tm@aol.com> - 2017-04-01 14:41 -0400
Re: struct padding question supercat@casperkitty.com - 2017-04-02 09:15 -0700
Re: struct padding question scott@slp53.sl.home (Scott Lurndal) - 2017-04-03 13:51 +0000
Re: struct padding question supercat@casperkitty.com - 2017-04-03 07:48 -0700
Re: struct padding question scott@slp53.sl.home (Scott Lurndal) - 2017-04-03 15:47 +0000
Re: struct padding question supercat@casperkitty.com - 2017-04-03 09:24 -0700
Re: struct padding question Keith Thompson <kst-u@mib.org> - 2017-04-01 11:43 -0700
Re: struct padding question Robert Wessel <robertwessel2@yahoo.com> - 2017-04-01 13:46 -0500
Re: struct padding question Keith Thompson <kst-u@mib.org> - 2017-04-01 12:00 -0700
Re: struct padding question Robert Wessel <robertwessel2@yahoo.com> - 2017-04-01 16:40 -0500
Re: struct padding question Keith Thompson <kst-u@mib.org> - 2017-04-01 15:24 -0700
Re: struct padding question Robert Wessel <robertwessel2@yahoo.com> - 2017-04-03 17:46 -0500
Re: struct padding question BartC <bc@freeuk.com> - 2017-03-23 11:50 +0000
Re: struct padding question David Brown <david.brown@hesbynett.no> - 2017-03-23 14:08 +0100
Re: struct padding question BartC <bc@freeuk.com> - 2017-03-23 13:31 +0000
Re: struct padding question David Brown <david.brown@hesbynett.no> - 2017-03-23 14:46 +0100
Re: struct padding question BartC <bc@freeuk.com> - 2017-03-23 14:07 +0000
Re: struct padding question David Brown <david.brown@hesbynett.no> - 2017-03-23 15:52 +0100
Re: struct padding question scott@slp53.sl.home (Scott Lurndal) - 2017-03-23 17:19 +0000
Re: struct padding question David Brown <david.brown@hesbynett.no> - 2017-03-23 19:57 +0100
Re: struct padding question Ian Pilcher <arequipeno@gmail.com> - 2017-03-23 08:52 -0500
Re: struct padding question David Brown <david.brown@hesbynett.no> - 2017-03-23 15:54 +0100
Re: struct padding question supercat@casperkitty.com - 2017-03-23 08:29 -0700
Re: struct padding question GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-03-23 14:04 +0100
Re: struct padding question MehdiAmini <atorrses@gmail.com> - 2017-03-23 20:32 +0430
Re: struct padding question GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-03-23 18:35 +0100
Re: struct padding question supercat@casperkitty.com - 2017-03-23 12:02 -0700
Re: struct padding question Keith Thompson <kst-u@mib.org> - 2017-03-23 12:21 -0700
Re: struct padding question supercat@casperkitty.com - 2017-03-23 12:55 -0700
Re: struct padding question Les Cargill <lcargill99@comcast.com> - 2017-03-25 15:12 -0500
Page 2 of 2 — ← Prev page 1 [2]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-03-23 13:31 +0000 |
| Message-ID | <ob0iif$qti$1@dont-email.me> |
| In reply to | #106796 |
On 23/03/2017 13:08, David Brown wrote: > On 23/03/17 12:50, BartC wrote: >> 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).
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-03-23 14:46 +0100 |
| Message-ID | <ob0jei$t0t$1@dont-email.me> |
| In reply to | #106798 |
On 23/03/17 14:31, BartC wrote: > On 23/03/2017 13:08, David Brown wrote: >> On 23/03/17 12:50, BartC wrote: > >>> 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.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-03-23 14:07 +0000 |
| Message-ID | <ob0kmg$2ut$1@dont-email.me> |
| In reply to | #106800 |
On 23/03/2017 13:46, David Brown wrote: > On 23/03/17 14:31, BartC wrote: >> 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 > guess That's right; it it can't 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. '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
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-03-23 15:52 +0100 |
| Message-ID | <ob0n96$cah$1@dont-email.me> |
| In reply to | #106802 |
On 23/03/17 15:07, BartC wrote: > On 23/03/2017 13:46, David Brown wrote: >> On 23/03/17 14:31, BartC wrote: > >>> 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. > > The compiler cannot >> guess > > That's right; it it can't 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. > > '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. > > 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.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2017-03-23 17:19 +0000 |
| Message-ID | <VsTAA.128247$Bp6.93731@fx36.iad> |
| In reply to | #106804 |
David Brown <david.brown@hesbynett.no> writes: >On 23/03/17 15:07, BartC wrote: >> 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.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-03-23 19:57 +0100 |
| Message-ID | <ob15m8$4ef$1@dont-email.me> |
| In reply to | #106817 |
On 23/03/17 18:19, Scott Lurndal wrote: > David Brown <david.brown@hesbynett.no> writes: >> On 23/03/17 15:07, BartC wrote: > >>> 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.
[toc] | [prev] | [next] | [standalone]
| From | Ian Pilcher <arequipeno@gmail.com> |
|---|---|
| Date | 2017-03-23 08:52 -0500 |
| Message-ID | <ob0jot$u5u$1@dont-email.me> |
| In reply to | #106796 |
On 03/23/2017 08:08 AM, David Brown wrote: > 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 arequipeno@gmail.com -------- "I grew up before Mark Zuckerberg invented friendship" -------- ========================================================================
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-03-23 15:54 +0100 |
| Message-ID | <ob0nda$cah$2@dont-email.me> |
| In reply to | #106801 |
On 23/03/17 14:52, Ian Pilcher wrote: > On 03/23/2017 08:08 AM, David Brown wrote: >> 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.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-03-23 08:29 -0700 |
| Message-ID | <0ce7b882-7aff-434a-9268-dc151b1eb8ec@googlegroups.com> |
| In reply to | #106805 |
On Thursday, March 23, 2017 at 9:54:26 AM UTC-5, David Brown wrote:
> 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.
[toc] | [prev] | [next] | [standalone]
| From | GOTHIER Nathan <nathan.gothier@gmail.com> |
|---|---|
| Date | 2017-03-23 14:04 +0100 |
| Message-ID | <20170323140413.9a2515568baa60870b1b6570@gmail.com> |
| In reply to | #106789 |
On Thu, 23 Mar 2017 14:28:23 +0430
MehdiAmini <atorrses@gmail.com> wrote:
>
> // 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.
[toc] | [prev] | [next] | [standalone]
| From | MehdiAmini <atorrses@gmail.com> |
|---|---|
| Date | 2017-03-23 20:32 +0430 |
| Message-ID | <ob0rcp$s7g$1@dont-email.me> |
| In reply to | #106795 |
On 03/23/2017 05:34 PM, GOTHIER Nathan wrote:
> On Thu, 23 Mar 2017 14:28:23 +0430
> MehdiAmini <atorrses@gmail.com> wrote:
[...]
> 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.
[toc] | [prev] | [next] | [standalone]
| From | GOTHIER Nathan <nathan.gothier@gmail.com> |
|---|---|
| Date | 2017-03-23 18:35 +0100 |
| Message-ID | <20170323183521.27ca5598f993dd7a3b3d67cc@gmail.com> |
| In reply to | #106811 |
On Thu, 23 Mar 2017 20:32:15 +0430
MehdiAmini <atorrses@gmail.com> wrote:
> On 03/23/2017 05:34 PM, GOTHIER Nathan wrote:
> > On Thu, 23 Mar 2017 14:28:23 +0430
> > MehdiAmini <atorrses@gmail.com> wrote:
>
> [...]
>
> > 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.
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.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-03-23 12:02 -0700 |
| Message-ID | <6527496a-a2b4-44a0-90c3-9fda0475ca2e@googlegroups.com> |
| In reply to | #106811 |
On Thursday, March 23, 2017 at 11:02:23 AM UTC-5, Mehdi Amini Valashani son of Bahram wrote:
> > 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.
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.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-03-23 12:21 -0700 |
| Message-ID | <lnlgrvajeb.fsf@kst-u.example.com> |
| In reply to | #106840 |
supercat@casperkitty.com writes:
[...]
> 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-u@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"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-03-23 12:55 -0700 |
| Message-ID | <076e6416-bd2f-4c11-bd05-2882870dd498@googlegroups.com> |
| In reply to | #106842 |
On Thursday, March 23, 2017 at 2:22:02 PM UTC-5, Keith Thompson wrote:
> supercat writes:
> [...]
> > 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.
[toc] | [prev] | [next] | [standalone]
| From | Les Cargill <lcargill99@comcast.com> |
|---|---|
| Date | 2017-03-25 15:12 -0500 |
| Message-ID | <ob6ih2$nv$2@dont-email.me> |
| In reply to | #106789 |
MehdiAmini wrote:
>
> // 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
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c
csiph-web