Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #106789 > unrolled thread

struct padding question

Started byMehdiAmini <atorrses@gmail.com>
First post2017-03-23 14:28 +0430
Last post2017-03-25 15:12 -0500
Articles 16 on this page of 36 — 13 participants

Back to article view | Back to comp.lang.c


Contents

  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]


#106798

FromBartC <bc@freeuk.com>
Date2017-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]


#106800

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#106802

FromBartC <bc@freeuk.com>
Date2017-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]


#106804

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#106817

Fromscott@slp53.sl.home (Scott Lurndal)
Date2017-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]


#106837

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#106801

FromIan Pilcher <arequipeno@gmail.com>
Date2017-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]


#106805

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#106806

Fromsupercat@casperkitty.com
Date2017-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]


#106795

FromGOTHIER Nathan <nathan.gothier@gmail.com>
Date2017-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]


#106811

FromMehdiAmini <atorrses@gmail.com>
Date2017-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]


#106821

FromGOTHIER Nathan <nathan.gothier@gmail.com>
Date2017-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]


#106840

Fromsupercat@casperkitty.com
Date2017-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]


#106842

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#106846

Fromsupercat@casperkitty.com
Date2017-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]


#107062

FromLes Cargill <lcargill99@comcast.com>
Date2017-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