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


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

sizeof Data types

Started byReal Troll <real.troll@trolls.com>
First post2016-08-05 18:45 -0400
Last post2016-08-09 11:35 -0700
Articles 20 on this page of 52 — 20 participants

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


Contents

  sizeof Data types Real Troll <real.troll@trolls.com> - 2016-08-05 18:45 -0400
    sizeof Data types jameskuyper@verizon.net - 2016-08-05 17:10 -0700
    Re: sizeof Data types raltbos@xs4all.nl (Richard Bos) - 2016-08-06 10:35 +0000
    Re: sizeof Data types raltbos@xs4all.nl (Richard Bos) - 2016-08-06 10:36 +0000
    Re: sizeof Data types Jean-Marc Bourguet <jm@bourguet.org> - 2016-08-06 22:29 +0200
      Re: sizeof Data types Ken Brody <kenbrody@spamcop.net> - 2016-08-09 12:55 -0400
    Re: sizeof Data types BartC <bc@freeuk.com> - 2016-08-06 21:43 +0100
      Re: sizeof Data types jameskuyper@verizon.net - 2016-08-06 15:25 -0700
        Re: sizeof Data types David Brown <david.brown@hesbynett.no> - 2016-08-08 09:48 +0200
          Re: sizeof Data types James Kuyper <jameskuyper@verizon.net> - 2016-08-08 11:05 -0400
            Re: sizeof Data types David Brown <david.brown@hesbynett.no> - 2016-08-08 17:57 +0200
          Re: sizeof Data types supercat@casperkitty.com - 2016-08-08 08:36 -0700
            Re: sizeof Data types David Brown <david.brown@hesbynett.no> - 2016-08-08 19:05 +0200
              Re: sizeof Data types supercat@casperkitty.com - 2016-08-08 14:09 -0700
                Re: sizeof Data types David Brown <david.brown@hesbynett.no> - 2016-08-09 09:38 +0200
                  Re: sizeof Data types Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-09 11:23 +0100
                    Re: sizeof Data types Tim Rentsch <txr@alumni.caltech.edu> - 2016-08-12 07:42 -0700
                      Re: sizeof Data types Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-12 21:38 +0100
                  Re: sizeof Data types Keith Thompson <kst-u@mib.org> - 2016-08-09 08:12 -0700
                  Re: sizeof Data types supercat@casperkitty.com - 2016-08-10 10:36 -0700
                    Re: sizeof Data types Keith Thompson <kst-u@mib.org> - 2016-08-10 11:42 -0700
        Re: sizeof Data types Philip Lantz <prl@canterey.us> - 2016-08-11 10:20 -0700
          Re: sizeof Data types Keith Thompson <kst-u@mib.org> - 2016-08-11 12:04 -0700
          Re: sizeof Data types Tim Rentsch <txr@alumni.caltech.edu> - 2016-08-12 08:22 -0700
      Re: sizeof Data types Nobody <nobody@nowhere.invalid> - 2016-08-07 01:32 +0100
        Re: sizeof Data types Keith Thompson <kst-u@mib.org> - 2016-08-06 18:10 -0700
    Re: sizeof Data types Siri Cruise <chine.bleu@yahoo.com> - 2016-08-06 20:22 -0700
      Re: sizeof Data types Ian Collins <ian-news@hotmail.com> - 2016-08-07 15:40 +1200
      Re: sizeof Data types Ken Brody <kenbrody@spamcop.net> - 2016-08-09 13:06 -0400
        Re: sizeof Data types Siri Cruise <chine.bleu@yahoo.com> - 2016-08-09 12:37 -0700
          Re: sizeof Data types Tim Rentsch <txr@alumni.caltech.edu> - 2016-08-11 09:18 -0700
            Re: sizeof Data types Siri Cruise <chine.bleu@yahoo.com> - 2016-08-11 11:11 -0700
              Re: sizeof Data types Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-08-11 12:26 -0600
                Re: sizeof Data types David Brown <david.brown@hesbynett.no> - 2016-08-11 23:31 +0200
                  Re: sizeof Data types supercat@casperkitty.com - 2016-08-11 14:59 -0700
                Re: sizeof Data types Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-12 00:15 -0700
              Re: sizeof Data types Tim Rentsch <txr@alumni.caltech.edu> - 2016-08-12 08:05 -0700
    Re: sizeof Data types John Bode <jfbode1029@gmail.com> - 2016-08-08 12:38 -0700
      Re: sizeof Data types Ken Brody <kenbrody@spamcop.net> - 2016-08-09 13:08 -0400
        Re: sizeof Data types Keith Thompson <kst-u@mib.org> - 2016-08-09 10:43 -0700
        Re: sizeof Data types "James R. Kuyper" <jameskuyper@verizon.net> - 2016-08-09 13:41 -0400
          Re: sizeof Data types Ken Brody <kenbrody@spamcop.net> - 2016-08-10 11:51 -0400
            Re: sizeof Data types "James R. Kuyper" <jameskuyper@verizon.net> - 2016-08-10 12:35 -0400
              Re: sizeof Data types Ken Brody <kenbrody@spamcop.net> - 2016-08-11 11:53 -0400
                Re: sizeof Data types "James R. Kuyper" <jameskuyper@verizon.net> - 2016-08-13 11:29 -0400
                  Re: sizeof Data types supercat@casperkitty.com - 2016-08-13 09:18 -0700
            Re: sizeof Data types Keith Thompson <kst-u@mib.org> - 2016-08-10 10:13 -0700
              Re: sizeof Data types Ken Brody <kenbrody@spamcop.net> - 2016-08-11 11:56 -0400
    Re: sizeof Data types Ken Brody <kenbrody@spamcop.net> - 2016-08-09 12:59 -0400
      Re: sizeof Data types "James R. Kuyper" <jameskuyper@verizon.net> - 2016-08-09 13:49 -0400
        Re: sizeof Data types Ken Brody <kenbrody@spamcop.net> - 2016-08-10 12:08 -0400
      Re: sizeof Data types Keith Thompson <kst-u@mib.org> - 2016-08-09 11:35 -0700

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#92091

FromKeith Thompson <kst-u@mib.org>
Date2016-08-10 11:42 -0700
Message-ID<ln37mctqis.fsf@kst-u.example.com>
In reply to#92090
supercat@casperkitty.com writes:
> On Tuesday, August 9, 2016 at 2:38:28 AM UTC-5, David Brown wrote:
>> uint16_t is either "unsigned short", "unsigned int", or an unsigned
>> extended integer type of lower rank than "unsigned int".
>
> Is there any prohibition of extended integer types whose rank is between
> that of "int" and "long" (a lot of code for 8-bit micros could benefit from
> having a 24-bit type, for example)?

No.

>                                      If not, would there be any
> prohibition against int16_t and uint16_t ranking above "int" and "unsigned"?

Yes.  N1570 6.3.1.1:

    The rank of any standard integer type shall be greater than the rank
    of any extended integer type with the same width.

But int24_t and uint24_t could have a rank above int and below long.

[...]

-- 
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]


#92135

FromPhilip Lantz <prl@canterey.us>
Date2016-08-11 10:20 -0700
Message-ID<MPG.32116bba253f9da3119@news.eternal-september.org>
In reply to#91831
jameskuyper@verizon.net wrote:
> > If you need to have confidence as to how big exactly short, int, long or 
> > long long are, use instead the types specified in stdint.h:  int32_t, 
> > uint16_t etc.
> 
> "If you need to have confidence as to exactly how big" one of the
> standard types is, you should use sizeof find out. I think you mean
> "if you need an integer type with a specified size". Note that int32_t,
> etc. need not be any standard type - they could all be extended types
> - but if you need an exactly 32-bit type, int32_t is it (if supported
> - and if it isn't supported, you're trying to do something that can't
> be done on that platform).

Just to pick a nit (which we are all wont to do here, right?), it is
possible that a standard (or extended) integer type exists that meets
all the requirements of int32_t, but int32_t can't be defined because
there is no type that meets the requirements of uint32_t.

Philip

[toc] | [prev] | [next] | [standalone]


#92141

FromKeith Thompson <kst-u@mib.org>
Date2016-08-11 12:04 -0700
Message-ID<ln1t1vrutp.fsf@kst-u.example.com>
In reply to#92135
Philip Lantz <prl@canterey.us> writes:
> jameskuyper@verizon.net wrote:
>> > If you need to have confidence as to how big exactly short, int, long or 
>> > long long are, use instead the types specified in stdint.h:  int32_t, 
>> > uint16_t etc.
>> 
>> "If you need to have confidence as to exactly how big" one of the
>> standard types is, you should use sizeof find out. I think you mean
>> "if you need an integer type with a specified size". Note that int32_t,
>> etc. need not be any standard type - they could all be extended types
>> - but if you need an exactly 32-bit type, int32_t is it (if supported
>> - and if it isn't supported, you're trying to do something that can't
>> be done on that platform).
>
> Just to pick a nit (which we are all wont to do here, right?), it is
> possible that a standard (or extended) integer type exists that meets
> all the requirements of int32_t, but int32_t can't be defined because
> there is no type that meets the requirements of uint32_t.

Or, perhaps more plausibly, vice versa.  For example, a CPU might
support a type that meets the requirements of uint32_t, but it
use something other than 2's-complement for signed integers, or
signed integer types might have padding bits, or the representation
0x80000000 might be a trap representation.  Not likely on most
modern architectures, but certainly permitted by the standard.

-- 
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]


#92196

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-08-12 08:22 -0700
Message-ID<kfnpopef1vh.fsf@x-alumni2.alumni.caltech.edu>
In reply to#92135
Philip Lantz <prl@canterey.us> writes:

> jameskuyper@verizon.net wrote:
>>> If you need to have confidence as to how big exactly short, int, long or
>>> long long are, use instead the types specified in stdint.h:  int32_t,
>>> uint16_t etc.
>>
>> "If you need to have confidence as to exactly how big" one of the
>> standard types is, you should use sizeof find out.  I think you mean
>> "if you need an integer type with a specified size".  Note that int32_t,
>> etc.  need not be any standard type - they could all be extended types
>> - but if you need an exactly 32-bit type, int32_t is it (if supported
>> - and if it isn't supported, you're trying to do something that can't
>> be done on that platform).
>
> Just to pick a nit (which we are all wont to do here, right?), it is
> possible that a standard (or extended) integer type exists that meets
> all the requirements of int32_t, but int32_t can't be defined because
> there is no type that meets the requirements of uint32_t.

Right.  IIANM that can happen only if all of the candidate types for
int32_t have corresponding unsigned types that have a padding bit.
(There can be at most one, given that the corresponding signed type has
no padding bits.)

(Probably an unnecesary response, but when I started composing I thought
your comment was asking a question.  I think the question mark inside
the parentheses led me down the wrong garden path.)

[toc] | [prev] | [next] | [standalone]


#91833

FromNobody <nobody@nowhere.invalid>
Date2016-08-07 01:32 +0100
Message-ID<pan.2016.08.07.00.32.49.118000@nowhere.invalid>
In reply to#91830
On Sat, 06 Aug 2016 21:43:45 +0100, BartC wrote:

>   long double     (don't know)

8 or 10.

10 on Linux/x86, 8 on Windows or other architectures.

Some versions of MinGW have a version of gcc which uses 10 in spite of the
fact that the standard library functions are provided by MSVCRT, which is
built with MSVC, which uses 8. Fortunately, the Windows API rarely (if
ever) uses "long double", but you have to watch out for e.g. printf("%Ld").

[toc] | [prev] | [next] | [standalone]


#91834

FromKeith Thompson <kst-u@mib.org>
Date2016-08-06 18:10 -0700
Message-ID<ln7fbtxu2o.fsf@kst-u.example.com>
In reply to#91833
Nobody <nobody@nowhere.invalid> writes:
> On Sat, 06 Aug 2016 21:43:45 +0100, BartC wrote:
>
>>   long double     (don't know)
>
> 8 or 10.
>
> 10 on Linux/x86, 8 on Windows or other architectures.

I see 16 on Linux/x86-64.

> Some versions of MinGW have a version of gcc which uses 10 in spite of the
> fact that the standard library functions are provided by MSVCRT, which is
> built with MSVC, which uses 8. Fortunately, the Windows API rarely (if
> ever) uses "long double", but you have to watch out for e.g. printf("%Ld").

I think you mean "%Lf" (or "%Lg" or "%Le").

Incidentally, there's a workaround for MinGW's long double bug.  If you
define the macro __USE_MINGW_ANSI_STDIO as 1 before including <stdio.h>,
it will use its own implementation of printf rather than MSVCRT.  (I
don't know whether that also fixes problems with the long double math
functions.)

-- 
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]


#91840

FromSiri Cruise <chine.bleu@yahoo.com>
Date2016-08-06 20:22 -0700
Message-ID<chine.bleu-1E482F.20223606082016@news.eternal-september.org>
In reply to#91781
In article <no34bv$1rus$1@gioia.aioe.org>, Real Troll <real.troll@trolls.com> 
wrote:

> Does this look right for various basic data types:

Knowing is better than guessing. Part of my build is to compile and run a 
program like

    #include <stdio.h>
    int main (int argc, char **argv) {
        FILE *f = fopen("sizeof.h", "w");
        fprintf(f, "#ifndef sizeof_h\n#define sizeof_h\n"
        fprintf(f, "#define sizeofint %d\n", sizeof(int));
        fprintf(f, "#define sizeoflongint %d\n", sizeof(longint));
        fprintf(f, "#define sizeofintptr_t %d\n", sizeof(intptr_t));
        ...
        fprintf(f, "#endif\n");
        return 0;
    }

Then rest of my code can #include "sizeof.h" and make size based decisions in 
cpp and c.

-- 
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
'I desire mercy, not sacrifice.'
If you assume the final scene is a dying delusion as Tom Cruise drowns below
the Louvre, then Edge of Tomorrow has a happy ending. Kill Tom repeat..

[toc] | [prev] | [next] | [standalone]


#91841

FromIan Collins <ian-news@hotmail.com>
Date2016-08-07 15:40 +1200
Message-ID<e0nottFoda0U1@mid.individual.net>
In reply to#91840
On 08/ 7/16 03:22 PM, Siri Cruise wrote:
>
> Knowing is better than guessing. Part of my build is to compile and run a
> program like
>
>      #include <stdio.h>
>      int main (int argc, char **argv) {
>          FILE *f = fopen("sizeof.h", "w");
>          fprintf(f, "#ifndef sizeof_h\n#define sizeof_h\n"
>          fprintf(f, "#define sizeofint %d\n", sizeof(int));
>          fprintf(f, "#define sizeoflongint %d\n", sizeof(longint));
>          fprintf(f, "#define sizeofintptr_t %d\n", sizeof(intptr_t));
>          ...
>          fprintf(f, "#endif\n");
>          return 0;
>      }
>
> Then rest of my code can #include "sizeof.h" and make size based decisions in
> cpp and c.

Someone's bound to follow up telling you %d isn't the correct format 
specifier for size_t :)

-- 
Ian

[toc] | [prev] | [next] | [standalone]


#92023

FromKen Brody <kenbrody@spamcop.net>
Date2016-08-09 13:06 -0400
Message-ID<nod2hs$ubb$1@dont-email.me>
In reply to#91840
On 8/6/2016 11:22 PM, Siri Cruise wrote:
> In article <no34bv$1rus$1@gioia.aioe.org>, Real Troll <real.troll@trolls.com>
> wrote:
>
>> Does this look right for various basic data types:
>
> Knowing is better than guessing. Part of my build is to compile and run a
> program like
>
>     #include <stdio.h>
>     int main (int argc, char **argv) {
>         FILE *f = fopen("sizeof.h", "w");
>         fprintf(f, "#ifndef sizeof_h\n#define sizeof_h\n"
>         fprintf(f, "#define sizeofint %d\n", sizeof(int));
>         fprintf(f, "#define sizeoflongint %d\n", sizeof(longint));
>         fprintf(f, "#define sizeofintptr_t %d\n", sizeof(intptr_t));
>         ...
>         fprintf(f, "#endif\n");
>         return 0;
>     }
>
> Then rest of my code can #include "sizeof.h" and make size based decisions in
> cpp and c.

I assume you mean you want to use the size of things in a #if directive?

Note that many things can cause "sizeof.h" to become incorrect.  Moving to a 
new system and forgetting to run this program, for example.  Or telling the 
compiler to build 64-bit binaries rather than 32-bit.

Can you give a specific example where you feel that the preprocessor needs 
to know the sizeof() value?

-- 
Kenneth Brody

[toc] | [prev] | [next] | [standalone]


#92032

FromSiri Cruise <chine.bleu@yahoo.com>
Date2016-08-09 12:37 -0700
Message-ID<chine.bleu-BEBEE0.12373209082016@news.eternal-september.org>
In reply to#92023
In article <nod2hs$ubb$1@dont-email.me>, Ken Brody <kenbrody@spamcop.net> 
wrote:

> On 8/6/2016 11:22 PM, Siri Cruise wrote:
> > In article <no34bv$1rus$1@gioia.aioe.org>, Real Troll 
> > <real.troll@trolls.com>
> > wrote:
> >
> >> Does this look right for various basic data types:
> >
> > Knowing is better than guessing. Part of my build is to compile and run a
> > program like
> >
> >     #include <stdio.h>
> >     int main (int argc, char **argv) {
> >         FILE *f = fopen("sizeof.h", "w");
> >         fprintf(f, "#ifndef sizeof_h\n#define sizeof_h\n"
> >         fprintf(f, "#define sizeofint %d\n", sizeof(int));
> >         fprintf(f, "#define sizeoflongint %d\n", sizeof(longint));
> >         fprintf(f, "#define sizeofintptr_t %d\n", sizeof(intptr_t));
> >         ...
> >         fprintf(f, "#endif\n");
> >         return 0;
> >     }
> >
> > Then rest of my code can #include "sizeof.h" and make size based decisions 
> > in
> > cpp and c.
> 
> I assume you mean you want to use the size of things in a #if directive?
> 
> Note that many things can cause "sizeof.h" to become incorrect.  Moving to a 
> new system and forgetting to run this program, for example.  Or telling the 
> compiler to build 64-bit binaries rather than 32-bit.

Not if you compile this program with the same options as rest of the code.

> Can you give a specific example where you feel that the preprocessor needs 
> to know the sizeof() value?

typedef struct Object Object;
struct Object {Dictionary *plist; intptr_t data;}
typedef void (*Function)(void);


#if sizeof_float<=sizeof_intptr_t
    //  if a float is small enough, store inside the object.
    static inline float getfloatdata (Object obj) {
        intptr_t j = obj.data; float f; memcpy(&j, &f, sizeof_float);
        return f;
    }
    static inline float putfloatdata (Object obj, float data) {
        float f = data; intptr_t j = 0; memcpy(&f, &j, sizeof_float);
        obj.data = j; return obj;
    }
#else
    //  if a float too large, treat it like a double.
    #define getfloatdata getdoubledata
    #define putfloatdata putdoubledata
#endif

Dictionary *floatplist = ...floatplist_isfloat
                ...floatplist_lengthen
                ...floatplist_add...;
Object newfloat (float f) {
    return putfloatdata((Object){floatplist, 0}, f);
}
static bool floatplist_isfloat (Object obj) {return true;}
static Object floatplist_lengthen (Object obj) {
    return newdouble(getfloatdata(obj));
}
static Object floatplist_add (Object obj, Object arg) {
    return newfloat(getflaotdata(obj)+ getflaotdata(arg));
}


#if sizeof_double<=sizeof_intptr_t
    //  if a double is small enough, store inside the object.
    static inline double getdoubledata (Object obj) {
        intptr_t j = obj.data; double f; memcpy(&j, &f, sizeof_double);
        return f;
    }
    static inline double putdoubledata (Object obj, double data) {
        double f = data; intptr_t j = 0; memcpy(&f, &j, sizeof_double);
        obj.data = j; return obj;
    }
#else
    //  if a double too large, store a pointer to the double in the object.
    static inline double getdoubledata (Object obj) {
        double *p = (double*)obj.data; return *p;
    }
    static inline double putdoubledata (Object obj, double data) {
        if (!obj.data) obj.data = (intptr_t)malloc(sizeof_double);
        double *p = (double*)obj.data; *p = data; return obj;
    }
#endif

Dictionary *doubleplist = ...doubleplist_isdouble
                ...doubleplist_lengthen
                ...doubleplist_add...;
Object newfloat (double f) {
    return putdoubledata((Object){doubleplist, 0}, f);
}
static bool doubleplist_isdouble (Object obj) {return true;}
static Object doubleplist_add (Object obj, Object arg) {
    return newdouble(getdoubledata(obj)+getdoubledata(arg));
}


bool isfloat (Object obj) {
    bool (*plist_isfloat)(Object) = (bool(*)(Object))getplist(obj, "isfloat");
    return plist_isfloat ? plist_isfloat(obj) : false;
}
bool isdouble (Object obj) {
    bool (*plist_isdouble)(Object) = (bool(*)(Object))getplist(obj, "isdouble");
    return plist_isdouble ? plist_isdouble(obj) : false;
}
Object lengthen (Object obj) {
    Object (*plist_lengthen)(Object) =
            (Object(*)(Object))getplist(obj, "lengthen");
    return plist_lengthen ? plist_lengthen(obj) : obj;
}
Object add (Object obj, Object arg) {
    balanceArithmeticObjects(&obj, &arg);
    Object (*plist_add)(Object, Object) =
            Object(*)(Object, Object))getplist(obj, "add");
    return plist_add ? plist_add(obj, arg) : newdouble(NaN);
}


Object quadraticFormula (Object a, Object b, Object c) {
    Object p = subtract(newfloat(0), b);
    Object q = squareroot(subtract(multiply(b, b),
            multiply(multiply(newfloat(4, a), c)));
    Object r = multiply(newfloat(2), a);
    return newlist(2,
        divide(add(p, q), r),
        divide(subtract(p, q), r));
}


Actually an arithmetic Object can also be boolean, integer, long integer, 
natural, long natural, rational, float, double, long double, complex, and long 
complex. The time type is actually an alias to a double. So if the discriminant 
is negative the squareroot returns a complex object. In each case a value that 
can be jammed inside an intptr_t is otherwise it is a pointer to the value. This 
is all hidden inside the getTYPEdata and putTYPEdata functions.

Specific enough?

-- 
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
'I desire mercy, not sacrifice.'
If you assume the final scene is a dying delusion as Tom Cruise drowns below
the Louvre, then Edge of Tomorrow has a happy ending. Kill Tom repeat..

[toc] | [prev] | [next] | [standalone]


#92133

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-08-11 09:18 -0700
Message-ID<kfnbn0zgtyc.fsf@x-alumni2.alumni.caltech.edu>
In reply to#92032
Siri Cruise <chine.bleu@yahoo.com> writes:

> In article <nod2hs$ubb$1@dont-email.me>, Ken Brody <kenbrody@spamcop.net>
> wrote:
>
>> On 8/6/2016 11:22 PM, Siri Cruise wrote:
>>> In article <no34bv$1rus$1@gioia.aioe.org>, Real Troll
>>> <real.troll@trolls.com>
>>> wrote:
>>>
>>>> Does this look right for various basic data types:
>>>
>>> Knowing is better than guessing.  Part of my build is to compile and run a
>>> program like
>>>
>>>     #include <stdio.h>
>>>     int main (int argc, char **argv) {
>>>         FILE *f = fopen("sizeof.h", "w");
>>>         fprintf(f, "#ifndef sizeof_h\n#define sizeof_h\n"
>>>         fprintf(f, "#define sizeofint %d\n", sizeof(int));
>>>         fprintf(f, "#define sizeoflongint %d\n", sizeof(longint));
>>>         fprintf(f, "#define sizeofintptr_t %d\n", sizeof(intptr_t));
>>>         ...
>>>         fprintf(f, "#endif\n");
>>>         return 0;
>>>     }
>>>
>>> Then rest of my code can #include "sizeof.h" and make size based decisions
>>> in
>>> cpp and c.
>>
>> I assume you mean you want to use the size of things in a #if directive?
>>
>> Note that many things can cause "sizeof.h" to become incorrect.  Moving to a
>> new system and forgetting to run this program, for example.  Or telling the
>> compiler to build 64-bit binaries rather than 32-bit.
>
> Not if you compile this program with the same options as rest of the code.
>
>> Can you give a specific example where you feel that the preprocessor needs
>> to know the sizeof() value?
>
> typedef struct Object Object;
> struct Object {Dictionary *plist; intptr_t data;}
> typedef void (*Function)(void);
>
>
> #if sizeof_float<=sizeof_intptr_t
>     //  if a float is small enough, store inside the object.
>     static inline float getfloatdata (Object obj) {
>         intptr_t j = obj.data; float f; memcpy(&j, &f, sizeof_float);
>         return f;
>     }
>     static inline float putfloatdata (Object obj, float data) {
>         float f = data; intptr_t j = 0; memcpy(&f, &j, sizeof_float);
>         obj.data = j; return obj;
>     }
> #else
>     //  if a float too large, treat it like a double.
>     #define getfloatdata getdoubledata
>     #define putfloatdata putdoubledata
> #endif
>
> [...]
>
> #if sizeof_double<=sizeof_intptr_t
>     //  if a double is small enough, store inside the object.
>     static inline double getdoubledata (Object obj) {
>         intptr_t j = obj.data; double f; memcpy(&j, &f, sizeof_double);
>         return f;
>     }
>     static inline double putdoubledata (Object obj, double data) {
>         double f = data; intptr_t j = 0; memcpy(&f, &j, sizeof_double);
>         obj.data = j; return obj;
>     }
> #else
>     //  if a double too large, store a pointer to the double in the object.
>     static inline double getdoubledata (Object obj) {
>         double *p = (double*)obj.data; return *p;
>     }
>     static inline double putdoubledata (Object obj, double data) {
>         if (!obj.data) obj.data = (intptr_t)malloc(sizeof_double);
>         double *p = (double*)obj.data; *p = data; return obj;
>     }
> #endif
>
> [.. code that uses those ..]
>
> [...] In each case a value that can be jammed inside an intptr_t
> is otherwise it is a pointer to the value.  This is all hidden
> inside the getTYPEdata and putTYPEdata functions.
>
> Specific enough?

It is specific enough, and it illustrates why you did what you
did.  But I don't find the motivation compelling.  (Incidentally,
I think you have the arguments to memcpy() switched around in
some places.  Also I presume the return types for putfloatdata()
and putdoubledata() were simply misentered.)

The #define's for the case where sizeof_float > sizeof_intptr_t
are a bit strange.  They change the types of these functions,
and they cause float values to be stored as doubles.  I don't
know if this is what you meant or if it happened accidentally
as a code saving measure.  From here on I'm assuming it was
just an accident (and there are obvious modifications if it
was intentional).  This isn't a big deal, I mention it just
to be clear that I didn't overlook it.

The main point is the #if's for the function definitions are not
needed.  The functions can be written this way:

    static inline double getdoubledata (Object obj) {
        if (sizeof getdoubledata(obj) > sizeof obj.data) {
            return  *(double*)obj.data;
        } else {
            return (union { intptr_t i; double d; }){ obj.data }.d;
        }
    }

    static inline float getfloatdata (Object obj) {
        if (sizeof getfloatdata(obj) > sizeof obj.data) {
            return  *(float*)obj.data;
        } else {
            return (union { intptr_t i; float f; }){ obj.data }.f;
        }
    }

    static inline Object putdoubledata (Object obj, double data) {
        if (sizeof data > sizeof obj.data) {
            if(!obj.data) obj.data = (intptr_t)malloc( sizeof data );
            *(double*)obj.data = data;
        } else {
            obj.data = (union { double d; intptr_t i; }){ data }.i;
        }
        return  obj;
    }

    static inline Object putfloatdata (Object obj, float data) {
        if (sizeof data > sizeof obj.data) {
            if(!obj.data) obj.data = (intptr_t)malloc( sizeof data );
            *(float*)obj.data = data;
        } else {
            obj.data = (union { float f; intptr_t i; }){ data }.i;
        }
        return  obj;
    }

The various 'sizeof ...' tests are highly likely to be optimized
away.  (Running a very old gcc they were even at -O0.)  And I
think it is even more likely they will be optimized away in
circumstances where the 'inline' directive is operative (ie,
so actual inlining occurs).

Given the above, what is your view now for needing a header
with #define's for sizes of various types?

[toc] | [prev] | [next] | [standalone]


#92138

FromSiri Cruise <chine.bleu@yahoo.com>
Date2016-08-11 11:11 -0700
Message-ID<chine.bleu-47B1E9.11110111082016@news.eternal-september.org>
In reply to#92133
In article <kfnbn0zgtyc.fsf@x-alumni2.alumni.caltech.edu>,
 Tim Rentsch <txr@alumni.caltech.edu> wrote:

> The #define's for the case where sizeof_float > sizeof_intptr_t
> are a bit strange.  They change the types of these functions,
> and they cause float values to be stored as doubles.  I don't
> know if this is what you meant or if it happened accidentally
> as a code saving measure.  From here on I'm assuming it was
> just an accident (and there are obvious modifications if it
> was intentional).  This isn't a big deal, I mention it just
> to be clear that I didn't overlook it.

The only reason I know of to use a single float is to save space. When I have to 
store a value as a pointer to allocated memory, I've lost any space savings, so 
I use the more accurate double. My abandonned code that useds vector functions 
used floats because the functions are only defined on float[4].

-- 
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
'I desire mercy, not sacrifice.'
If you assume the final scene is a dying delusion as Tom Cruise drowns below
the Louvre, then Edge of Tomorrow has a happy ending. Kill Tom repeat..

[toc] | [prev] | [next] | [standalone]


#92140

FromJoe Pfeiffer <pfeiffer@cs.nmsu.edu>
Date2016-08-11 12:26 -0600
Message-ID<1bshub5fid.fsf@pfeifferfamily.net>
In reply to#92138
Siri Cruise <chine.bleu@yahoo.com> writes:

> In article <kfnbn0zgtyc.fsf@x-alumni2.alumni.caltech.edu>,
>  Tim Rentsch <txr@alumni.caltech.edu> wrote:
>
>> The #define's for the case where sizeof_float > sizeof_intptr_t
>> are a bit strange.  They change the types of these functions,
>> and they cause float values to be stored as doubles.  I don't
>> know if this is what you meant or if it happened accidentally
>> as a code saving measure.  From here on I'm assuming it was
>> just an accident (and there are obvious modifications if it
>> was intentional).  This isn't a big deal, I mention it just
>> to be clear that I didn't overlook it.
>
> The only reason I know of to use a single float is to save space. When
> I have to
> store a value as a pointer to allocated memory, I've lost any space savings, so 
> I use the more accurate double. My abandonned code that useds vector functions 
> used floats because the functions are only defined on float[4].

This is of dubious relevance, but floats turn out to be much, much
faster than doubles in GPUs.

[toc] | [prev] | [next] | [standalone]


#92169

FromDavid Brown <david.brown@hesbynett.no>
Date2016-08-11 23:31 +0200
Message-ID<noiqr8$r7u$2@dont-email.me>
In reply to#92140
On 11/08/16 20:26, Joe Pfeiffer wrote:
> Siri Cruise <chine.bleu@yahoo.com> writes:
>
>> In article <kfnbn0zgtyc.fsf@x-alumni2.alumni.caltech.edu>,
>>   Tim Rentsch <txr@alumni.caltech.edu> wrote:
>>
>>> The #define's for the case where sizeof_float > sizeof_intptr_t
>>> are a bit strange.  They change the types of these functions,
>>> and they cause float values to be stored as doubles.  I don't
>>> know if this is what you meant or if it happened accidentally
>>> as a code saving measure.  From here on I'm assuming it was
>>> just an accident (and there are obvious modifications if it
>>> was intentional).  This isn't a big deal, I mention it just
>>> to be clear that I didn't overlook it.
>>
>> The only reason I know of to use a single float is to save space. When
>> I have to
>> store a value as a pointer to allocated memory, I've lost any space savings, so
>> I use the more accurate double. My abandonned code that useds vector functions
>> used floats because the functions are only defined on float[4].
>
> This is of dubious relevance, but floats turn out to be much, much
> faster than doubles in GPUs.
>

They are also much faster than doubles on most embedded systems (other 
than "big" embedded systems).  For most microcontrollers, floating point 
is done in software and single-precision is a lot faster than double 
precision.  There is also a substantial class of microcontrollers with 
cpu hardware for single-precision floating point, but doubles are done 
in software - there the difference is even greater, and you have to take 
care in your coding to avoid accidentally using doubles.

[toc] | [prev] | [next] | [standalone]


#92172

Fromsupercat@casperkitty.com
Date2016-08-11 14:59 -0700
Message-ID<66320053-a28b-47bd-88ef-446fa242b689@googlegroups.com>
In reply to#92169
On Thursday, August 11, 2016 at 4:31:26 PM UTC-5, David Brown wrote:
> They are also much faster than doubles on most embedded systems (other 
> than "big" embedded systems).  For most microcontrollers, floating point 
> is done in software and single-precision is a lot faster than double 
> precision.

On many microcontrollers and microprocessors, the IEEE-754 double is not
very good as a computation type.  A type with an unpacked 64-bit significand
with an explicit leading 1 will be faster to work with in addition to
offering better precision; while IEEE-754 never standardized an "extended
single" type, a type with an unpacked 32-bit significand and a separate
exponent would often be somewhat faster to work with than an IEEE single
while offering better precision.  Even if such a type were no smaller than
"double", it would offer performance that was much faster than "double"
and sometimes faster than "float"(*) while offering better precision than
the latter.  If the Standard were to reduce the minimum requirements for
double precision slightly, at least for freestanding implementations, such
a type would for many applications be more useful than "double".

(*) Copying a 64-byte "long float" as described would take twice as long as
    copying a 32-byte "float", but many operations with "long float" would
    be slightly faster; chained addition and subtraction could be
    significantly faster in some cases where expensive normalization steps
    could be omitted.

[toc] | [prev] | [next] | [standalone]


#92179

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2016-08-12 00:15 -0700
Message-ID<49806dd2-6097-4db1-937e-b0f81858ee3b@googlegroups.com>
In reply to#92140
On Thursday, August 11, 2016 at 7:26:11 PM UTC+1, Joe Pfeiffer wrote:
> 
> This is of dubious relevance, but floats turn out to be much, much
> faster than doubles in GPUs.
>
You often have to interact with hardware, and it's often inconvenient
and slow to write little converter functions before passing data to
and from a GPU.

[toc] | [prev] | [next] | [standalone]


#92193

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-08-12 08:05 -0700
Message-ID<kfny442f2od.fsf@x-alumni2.alumni.caltech.edu>
In reply to#92138
Siri Cruise <chine.bleu@yahoo.com> writes:

> In article <kfnbn0zgtyc.fsf@x-alumni2.alumni.caltech.edu>,
>  Tim Rentsch <txr@alumni.caltech.edu> wrote:
>
>> The #define's for the case where sizeof_float > sizeof_intptr_t
>> are a bit strange.  They change the types of these functions,
>> and they cause float values to be stored as doubles.  I don't
>> know if this is what you meant or if it happened accidentally
>> as a code saving measure.  From here on I'm assuming it was
>> just an accident (and there are obvious modifications if it
>> was intentional).  This isn't a big deal, I mention it just
>> to be clear that I didn't overlook it.
>
> The only reason I know of to use a single float is to save space.
> When I have to store a value as a pointer to allocated memory,
> I've lost any space savings, so I use the more accurate double.
> My abandonned code that useds vector functions used floats because
> the functions are only defined on float[4].

The point of my comment is not about space but code quality.  As
written in your post the code looks brittle.  Also there seems to
be no point to widening the stored value, since the value to be
stored comes from a 'float' parameter.  Here is an excerpt from
the original long posting:

[..the following from Siri Cruise just slightly upthread..]
> Dictionary *floatplist = ...floatplist_isfloat
>                 ...floatplist_lengthen
>                 ...floatplist_add...;
> Object newfloat (float f) {
>     return putfloatdata((Object){floatplist, 0}, f);
> }
> static bool floatplist_isfloat (Object obj) {return true;}
> static Object floatplist_lengthen (Object obj) {
>     return newdouble(getfloatdata(obj));
> }
> static Object floatplist_add (Object obj, Object arg) {
>     return newfloat(getflaotdata(obj)+ getflaotdata(arg));
> }

Extra precision is stored but then it is thrown away when
newfloat() is called (eg, in floatplist_add()).  That by itself
is enough of a red flag to be called out in a code review.

I'm still wondering what your response is to the more significant
question, about using if() rather than #if, and thus avoiding the
need for the generated header file defining size-related symbols
for use in the preprocessor.

[toc] | [prev] | [next] | [standalone]


#91987

FromJohn Bode <jfbode1029@gmail.com>
Date2016-08-08 12:38 -0700
Message-ID<de7129d4-a523-4a52-b153-56d61f302927@googlegroups.com>
In reply to#91781
On Friday, August 5, 2016 at 5:35:54 PM UTC-5, Real Troll wrote:
> Does this look right for various basic data types:
> 
> > Storage size for char : 1
> > Storage size for signed char : 1
> > Storage size for unsigned char : 1

The size of a char type (signed, unsigned, etc.) is 1 storage unit (byte)
*by definition*.
  
The size of individual bytes must be *at least* 8 bits wide, but may be 
wider.  

> > Storage size for int : 4
> > Storage size for unsigned int : 4
> > Storage size for float : 4
> > Storage size for double : 8
> > Storage size for short : 2
> > Storage size for unsigned short : 2
> > Storage size for long : 4
> > Storage size for unsigned long : 4

For these types, the C language definition only mandates the range of values
they must be able to represent, not the form of that representation.  For 
example, the int type must be able to represent *at least* the range 
[-32767,32767], meaning it must be *at least* 16 bits wide, but it may be 
wider (note that range does not assume two's complement representation).  
Same for short and long.  

Float and double must each be able to represent a minimum range
with a minimum precision, but again the exact representation is not 
specified.  IEEE-754 is common, but not universal.  

C99 introduced fixed-size types like int16_t and uint32_t which take up
exactly as many bits as it says on the label, but they don't have to be 
supported by an implementation.  

[toc] | [prev] | [next] | [standalone]


#92024

FromKen Brody <kenbrody@spamcop.net>
Date2016-08-09 13:08 -0400
Message-ID<nod2mm$ubb$2@dont-email.me>
In reply to#91987
On 8/8/2016 3:38 PM, John Bode wrote:
[...]
> C99 introduced fixed-size types like int16_t and uint32_t which take up
> exactly as many bits as it says on the label, but they don't have to be
> supported by an implementation.

My complaint is that, AFAIK, they didn't specify a way for you to know if a 
given size is supported, short of having the compile fail on you if you used it.

If there is a way, please let me know.

-- 
Kenneth Brody

[toc] | [prev] | [next] | [standalone]


#92026

FromKeith Thompson <kst-u@mib.org>
Date2016-08-09 10:43 -0700
Message-ID<ln1t1xvnw9.fsf@kst-u.example.com>
In reply to#92024
Ken Brody <kenbrody@spamcop.net> writes:
> On 8/8/2016 3:38 PM, John Bode wrote:
> [...]
>> C99 introduced fixed-size types like int16_t and uint32_t which take up
>> exactly as many bits as it says on the label, but they don't have to be
>> supported by an implementation.
>
> My complaint is that, AFAIK, they didn't specify a way for you to know
> if a given size is supported, short of having the compile fail on you
> if you used it.
>
> If there is a way, please let me know.

#include <stdint.h>
...
#ifdef INT32_MAX
    puts("This system has int32_t");
#else
    puts("This system does not have int32_t");
#endif

Writing appropriate code for the #else branch is left as an exercise.
(Very often failing to compile is the best thing to do.)

-- 
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]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web