Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #127173 > unrolled thread
| Started by | James Harris <james.harris.1@gmail.com> |
|---|---|
| First post | 2018-03-01 14:40 +0000 |
| Last post | 2018-03-14 13:39 +0100 |
| Articles | 20 on this page of 103 — 17 participants |
Back to article view | Back to comp.lang.c
Compiling and linking code from different places in the file system James Harris <james.harris.1@gmail.com> - 2018-03-01 14:40 +0000
Re: Compiling and linking code from different places in the file system bartc <bc@freeuk.com> - 2018-03-01 14:55 +0000
Re: Compiling and linking code from different places in the file system James Harris <james.harris.1@gmail.com> - 2018-03-02 21:05 +0000
Re: Compiling and linking code from different places in the file system bartc <bc@freeuk.com> - 2018-03-03 01:18 +0000
Re: Compiling and linking code from different places in the file system James Harris <james.harris.1@gmail.com> - 2018-03-09 01:03 +0000
Re: Compiling and linking code from different places in the file system Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 22:37 -0800
Re: Compiling and linking code from different places in the file system James Harris <james.harris.1@gmail.com> - 2018-03-09 01:23 +0000
Re: Compiling and linking code from different places in the file system "James R. Kuyper" <jameskuyper@verizon.net> - 2018-03-01 11:11 -0500
Re: Compiling and linking code from different places in the file system "James R. Kuyper" <jameskuyper@verizon.net> - 2018-03-01 13:51 -0500
Re: Compiling and linking code from different places in the file system Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 11:02 -0800
Re: Compiling and linking code from different places in the file system James Harris <james.harris.1@gmail.com> - 2018-03-03 09:48 +0000
Re: Compiling and linking code from different places in the file system Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-03 04:06 -0800
Re: Compiling and linking code from different places in the file system Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-03 05:24 -0800
Re: Compiling and linking code from different places in the file system Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-03 06:43 -0800
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-06 13:51 -0800
Re: Compiling and linking code from different places in the file system Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-03-01 22:46 +0000
Re: Compiling and linking code from different places in the file system Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 15:27 -0800
Re: Compiling and linking code from different places in the file system James Harris <james.harris.1@gmail.com> - 2018-03-03 12:25 +0000
Re: Compiling and linking code from different places in the file system Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-03 04:53 -0800
Re: Compiling and linking code from different places in the file system bartc <bc@freeuk.com> - 2018-03-03 15:32 +0000
Re: Compiling and linking code from different places in the file system Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-03 08:02 -0800
Re: Compiling and linking code from different places in the file system Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-03-04 07:52 +0000
Re: Compiling and linking code from different places in the file system James Harris <james.harris.1@gmail.com> - 2018-03-04 08:43 +0000
Re: Compiling and linking code from different places in the file system Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-03-05 07:58 +0000
Re: Compiling and linking code from different places in the file system James Harris <james.harris.1@gmail.com> - 2018-03-06 21:37 +0000
Re: Compiling and linking code from different places in the file system Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-03-07 21:02 +0000
Re: Compiling and linking code from different places in the file system bartc <bc@freeuk.com> - 2018-03-05 15:29 +0000
Re: Compiling and linking code from different places in the file system James Harris <james.harris.1@gmail.com> - 2018-03-07 04:54 +0000
Re: Compiling and linking code from different places in the file system Robert Wessel <robertwessel2@yahoo.com> - 2018-03-07 00:33 -0600
Re: Compiling and linking code from different places in the file system James Harris <james.harris.1@gmail.com> - 2018-03-07 09:55 +0000
Re: Compiling and linking code from different places in the file system Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-03-04 07:39 +0000
Re: Compiling and linking code from different places in the file system Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-03-07 05:00 -0800
Re: Compiling and linking code from different places in the file system bartc <bc@freeuk.com> - 2018-03-07 14:09 +0000
Re: Compiling and linking code from different places in the file system Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-03-07 14:26 +0000
Re: Compiling and linking code from different places in the file system bartc <bc@freeuk.com> - 2018-03-07 16:35 +0000
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-07 09:32 -0800
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-07 10:11 -0800
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-07 11:12 -0800
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-07 12:01 -0800
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-07 15:43 -0800
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-07 19:18 -0800
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-08 09:59 -0800
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-08 10:28 -0800
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-08 13:36 -0800
Re: Compiling and linking code from different places in the file system bartc <bc@freeuk.com> - 2018-03-08 21:47 +0000
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-08 15:03 -0800
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-09 09:59 +0100
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-09 10:33 -0800
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-09 12:27 -0800
Re: Compiling and linking code from different places in the file system scott@slp53.sl.home (Scott Lurndal) - 2018-03-09 20:48 +0000
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-09 13:31 -0800
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-10 18:31 +0100
Re: Compiling and linking code from different places in the file system Robert Wessel <robertwessel2@yahoo.com> - 2018-03-10 13:22 -0600
Re: Compiling and linking code from different places in the file system Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-03-10 19:15 +0000
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-09 13:28 -0800
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-09 14:13 -0800
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-09 14:45 -0800
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-10 17:39 +0100
Re: Compiling and linking code from different places in the file system Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-03-10 19:00 +0000
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-12 08:26 -0700
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-12 17:06 +0100
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-12 10:23 -0700
Re: Compiling and linking code from different places in the file system scott@slp53.sl.home (Scott Lurndal) - 2018-03-12 18:42 +0000
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-12 12:20 -0700
Re: Compiling and linking code from different places in the file system scott@slp53.sl.home (Scott Lurndal) - 2018-03-12 20:27 +0000
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-12 14:12 -0700
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-13 11:12 +0100
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-12 09:23 -0700
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-12 10:38 -0700
Re: Compiling and linking code from different places in the file system David Kleinecke <dkleinecke@gmail.com> - 2018-03-12 11:41 -0700
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-12 12:10 -0700
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-09 12:09 -0800
Re: Compiling and linking code from different places in the file system scott@slp53.sl.home (Scott Lurndal) - 2018-03-09 20:46 +0000
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-10 18:35 +0100
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-12 08:54 -0700
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-13 08:39 +0100
Re: Compiling and linking code from different places in the file system Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-17 11:03 -0700
Re: Compiling and linking code from different places in the file system James Harris <james.harris.1@gmail.com> - 2018-03-11 07:37 +0000
Re: Compiling and linking code from different places in the file system David Kleinecke <dkleinecke@gmail.com> - 2018-03-11 14:22 -0700
Re: Compiling and linking code from different places in the file system Spiros Bousbouras <spibou@gmail.com> - 2018-03-11 21:48 +0000
Re: Compiling and linking code from different places in the file system David Kleinecke <dkleinecke@gmail.com> - 2018-03-11 17:50 -0700
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-11 15:54 -0700
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-12 09:38 -0700
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-08 10:48 +0100
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-08 09:58 -0800
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-08 22:03 +0100
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-08 13:55 -0800
Re: Compiling and linking code from different places in the file system Spiros Bousbouras <spibou@gmail.com> - 2018-03-08 22:38 +0000
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-08 15:03 -0800
Re: Compiling and linking code from different places in the file system Spiros Bousbouras <spibou@gmail.com> - 2018-03-08 23:15 +0000
Re: Compiling and linking code from different places in the file system Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-17 10:44 -0700
Re: Compiling and linking code from different places in the file system Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-18 03:47 -0700
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-09 10:10 +0100
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-09 10:10 -0800
Re: Compiling and linking code from different places in the file system jameskuyper@verizon.net - 2018-03-08 14:21 -0800
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-08 15:10 -0800
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-09 10:13 +0100
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-09 10:10 -0800
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-08 10:28 +0100
Re: Compiling and linking code from different places in the file system supercat@casperkitty.com - 2018-03-08 10:28 -0800
Re: Compiling and linking code from different places in the file system David Brown <david.brown@hesbynett.no> - 2018-03-08 22:17 +0100
Re: Compiling and linking code from different places in the file system Keith Thompson <kst-u@mib.org> - 2018-03-08 13:26 -0800
Re: Compiling and linking code from different places in the file system "Pascal J. Bourguignon" <pjb@informatimago.com> - 2018-03-14 13:39 +0100
Page 5 of 6 — ← Prev page 1 2 3 4 [5] 6 Next page →
| From | David Kleinecke <dkleinecke@gmail.com> |
|---|---|
| Date | 2018-03-11 17:50 -0700 |
| Message-ID | <a1780751-20a4-417e-a4fc-65c9ddf91099@googlegroups.com> |
| In reply to | #127643 |
On Sunday, March 11, 2018 at 2:48:10 PM UTC-7, Spiros Bousbouras wrote:
> On Sun, 11 Mar 2018 14:22:02 -0700 (PDT)
> David Kleinecke <dkleinecke@gmail.com> wrote:
> > On Saturday, March 10, 2018 at 11:37:20 PM UTC-8, James Harris wrote:
> > > On 08/03/2018 17:59, supercat@casperkitty.com wrote:
> > >
> > > ...
> > >
> > > > Which of the following would you consider more legible:
> > > >
> > > > uint32_t x,y; uint16_t small; uint64_t big
> > > > printf("x=%ld y=%ld small=%d big=%lld", x, y, small, big);
> > > > or
> > > > printf("x=%" PRId32 " y=%" PRId32 " small=%" PRId16 " big=%" PRId64,
> > > > x, y, small, big);
> > >
> > > While agreeing with your basic point that such macros are ugly they can
> > > be split into separate statements such as
> > >
> > > printf("x=%" PRId32, x);
> > > printf(" y=%" PRId32, y);
> > > printf(" small=%" PRId16, small);
> > > printf(" big=%" PRId64, big);
> > >
> > > That's legible and portable.
>
> PRId* are for signed integers ; correct are PRIu* .
>
> >
> > I dunno. What about
> > printf("x=%ld", x);
> > printf(" y=%ld", y);
> > printf(" small=%d", small);
> > printf(" big=%lld", big);
> > ?
>
> Each one of your constructs is undefined behaviour. For example %ld is for
> long int which is signed and will be at least 32 bit but could be more
> whereas uint32_t is unsigned and has exactly 32 bit.
Ah so - I remain stuck back at C89
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-03-11 15:54 -0700 |
| Message-ID | <lny3iyb4v6.fsf@kst-u.example.com> |
| In reply to | #127641 |
David Kleinecke <dkleinecke@gmail.com> writes:
> On Saturday, March 10, 2018 at 11:37:20 PM UTC-8, James Harris wrote:
>> On 08/03/2018 17:59, supercat@casperkitty.com wrote:
>> > Which of the following would you consider more legible:
>> >
>> > uint32_t x,y; uint16_t small; uint64_t big
>> > printf("x=%ld y=%ld small=%d big=%lld", x, y, small, big);
>> > or
>> > printf("x=%" PRId32 " y=%" PRId32 " small=%" PRId16 " big=%" PRId64,
>> > x, y, small, big);
Legibility is not particularly important for incorrect code.
>> While agreeing with your basic point that such macros are ugly they can
>> be split into separate statements such as
>>
>> printf("x=%" PRId32, x);
>> printf(" y=%" PRId32, y);
>> printf(" small=%" PRId16, small);
>> printf(" big=%" PRId64, big);
>>
>> That's legible and portable.
Almost. They should be PRIu32, PRIu32, PRIu16, and PRIu64, respectively.
> I dunno. What about
> printf("x=%ld", x);
> printf(" y=%ld", y);
> printf(" small=%d", small);
> printf(" big=%lld", big);
> ?
They're incorrect, or at least non-portable.
"%ld" requires an argument of type long int. x is of type uint32_t,
which is certainly not the same type, and may or may not be the same
size.
Remember, the format specifies like "%d", "%ld", and so forth require
arguments of specific *types*, not specific sizes.
--
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 | 2018-03-12 09:38 -0700 |
| Message-ID | <a5d6945f-6810-4f0e-8e3e-0118239ab692@googlegroups.com> |
| In reply to | #127625 |
On Sunday, March 11, 2018 at 1:37:20 AM UTC-6, James Harris wrote:
> On 08/03/2018 17:59, supercat@casperkitty.com wrote:
> > Which of the following would you consider more legible:
> >
> > uint32_t x,y; uint16_t small; uint64_t big
> > printf("x=%ld y=%ld small=%d big=%lld", x, y, small, big);
> > or
> > printf("x=%" PRId32 " y=%" PRId32 " small=%" PRId16 " big=%" PRId64,
> > x, y, small, big);
>
> While agreeing with your basic point that such macros are ugly they can
> be split into separate statements such as
>
> printf("x=%" PRId32, x);
> printf(" y=%" PRId32, y);
> printf(" small=%" PRId16, small);
> printf(" big=%" PRId64, big);
>
> That's legible and portable.
If the programmer had thought a printf would be better written over
multiple lines, the original would have been written that way. A
nicer solution would have been to have a type-safe way of passing
variadic arguments. That would not have been practical in the days
when a compiler that saw:
void foo();
foo(1,2,3.4,someInt);
would have no idea whether the function would be expecting two "int"
arguments and a "double", or an "int" and a type-safe argument list.
Since that the Standard would allow a compiler to assume that such
a call could only be to the former, however, that would no longer be
an issue.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2018-03-08 10:48 +0100 |
| Message-ID | <p7r0t0$tud$1@dont-email.me> |
| In reply to | #127454 |
On 08/03/18 00:43, supercat@casperkitty.com wrote: > On Wednesday, March 7, 2018 at 2:01:32 PM UTC-6, Keith Thompson wrote: >> supercat@casperkitty.com writes: >>> A lot of code was written before C99 added int32_t and uint32_t as >>> standards. The closest things to standard 32-bit type were "long" and >>> "unsigned long", and an assumption that "long" would be 32 bits was >>> about as portable as an assumption that "char" would be eight. A >>> machine with 36-bit words wouldn't have a 32-bit long, but it wouldn't >>> have an 8-bit "char" either. >> >> Yes, but int32_t and uint32_t do exist now. Are you looking for new and >> improved ways to update the C90 standard? They did that, and it's >> called C99 (and C11). > > Some embedded platforms have a limited range of compilers available. Name one current embedded platform that does not support <stdint.h>. I have a few C90-only compilers on my system. The one I have checked that is from this century has <stdint.h> even though it does not support much of C99. For the others, the chips they support have not been manufactured for over a decade. And then name one where you could not do this to get valid int32_t and uint32_t types: #include <limits.h> #if INT_MIN == -2147483647 typedef int int32_t; typedef unsigned int uint32_t; #elif LONG_MIN == -2147483647 typedef long int int32_t; typedef unsigned long int uint32_t; #elif SCHAR_MIN == -2147483647 typedef signed char int32_t; typedef unsigned char uint32_t; #else #error No support for 32-bit sized types #endif And then name one where you think using "long" would be a better idea than using something like that. > If > one needs to update the code for a piece of existing hardware which uses > an obscure platform, it may not be possible to use a C99 compiler. Use > of uint32_t probably wouldn't be a problem even on old compilers (since > pre-defining a macro with that name would likely work) but I'm curious what > justification there is for code that would require "long" to be 64 bits. 64-bit processing pre-dates C99. When creating compilers and ABI's for such platforms, the choice was between 64-bit long or compiler-specific extensions. Since C99, I would be surprised to see code that /required/ long to be 64 bits, since you have types int64_t and "long long" available. The point is to make code correct whatever (allowed) size "long" is. <snip> >> Is the lack of predefined BIG_ENDIAN and LITTLE_ENDIAN macros (however >> they're spelled) a real problem for people writing such code? It's not >> hard to incorporate that into a configuration script. > > Not every build system uses Unix. > > A configuration script will only be usable on build systems that support the > tools it's designed to work with. A text file that says to invoke the > compiler in a way that pre-defines either BIG_ENDIAN or LITTLE_ENDIAN will > work on any compiler that allows macros to be pre-defined at the time of > invocation. Configuration scripts are not limited to Unix. And it is merely an implementation detail whether such settings are handled by a configuration script, a "wizard", a "platform.h" configuration header, or whatever.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-03-08 09:58 -0800 |
| Message-ID | <lnina6e9fs.fsf@kst-u.example.com> |
| In reply to | #127464 |
David Brown <david.brown@hesbynett.no> writes:
[...]
> And then name one where you could not do this to get valid int32_t and
> uint32_t types:
>
> #include <limits.h>
>
> #if INT_MIN == -2147483647
> typedef int int32_t;
> typedef unsigned int uint32_t;
> #elif LONG_MIN == -2147483647
> typedef long int int32_t;
> typedef unsigned long int uint32_t;
> #elif SCHAR_MIN == -2147483647
> typedef signed char int32_t;
> typedef unsigned char uint32_t;
> #else
> #error No support for 32-bit sized types
> #endif
You mean -2147483648, not -2147483647. And the expression -2147483648
can be problematic. I'd check the value of INT_MAX (and I'd likely use
0x7fffffff because it's easier to see typos).
[...]
--
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 | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2018-03-08 22:03 +0100 |
| Message-ID | <p7s8ej$8ln$1@dont-email.me> |
| In reply to | #127488 |
On 08/03/18 18:58, Keith Thompson wrote: > David Brown <david.brown@hesbynett.no> writes: > [...] >> And then name one where you could not do this to get valid int32_t and >> uint32_t types: >> >> #include <limits.h> >> >> #if INT_MIN == -2147483647 >> typedef int int32_t; >> typedef unsigned int uint32_t; >> #elif LONG_MIN == -2147483647 >> typedef long int int32_t; >> typedef unsigned long int uint32_t; >> #elif SCHAR_MIN == -2147483647 >> typedef signed char int32_t; >> typedef unsigned char uint32_t; >> #else >> #error No support for 32-bit sized types >> #endif > > You mean -2147483648, not -2147483647. And the expression -2147483648 > can be problematic. I'd check the value of INT_MAX (and I'd likely use > 0x7fffffff because it's easier to see typos). > Yes, I meant -2147483648 - and yes, hex is easier in this case. But I did mean to check INT_MIN rather than INT_MAX - because (as far as I can see) that check will also ensure that the representation is two's complement and not one's complement or sign magnitude (which could have INT_MAX equal to 2147483647 and INT_MIN equal to -2147483647). For C99 compatible int32_t and uint32_t types, int32_t must be two's complement. Perhaps checking for (INT_MIN + 1) == -0x7fffffff would avoid any possible problems?
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-03-08 13:55 -0800 |
| Message-ID | <ln6066dygq.fsf@kst-u.example.com> |
| In reply to | #127500 |
David Brown <david.brown@hesbynett.no> writes:
> On 08/03/18 18:58, Keith Thompson wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>> [...]
>>> And then name one where you could not do this to get valid int32_t and
>>> uint32_t types:
>>>
>>> #include <limits.h>
>>>
>>> #if INT_MIN == -2147483647
>>> typedef int int32_t;
>>> typedef unsigned int uint32_t;
>>> #elif LONG_MIN == -2147483647
>>> typedef long int int32_t;
>>> typedef unsigned long int uint32_t;
>>> #elif SCHAR_MIN == -2147483647
>>> typedef signed char int32_t;
>>> typedef unsigned char uint32_t;
>>> #else
>>> #error No support for 32-bit sized types
>>> #endif
>>
>> You mean -2147483648, not -2147483647. And the expression -2147483648
>> can be problematic. I'd check the value of INT_MAX (and I'd likely use
>> 0x7fffffff because it's easier to see typos).
>>
>
> Yes, I meant -2147483648 - and yes, hex is easier in this case.
>
> But I did mean to check INT_MIN rather than INT_MAX - because (as far as
> I can see) that check will also ensure that the representation is two's
> complement and not one's complement or sign magnitude (which could have
> INT_MAX equal to 2147483647 and INT_MIN equal to -2147483647). For C99
> compatible int32_t and uint32_t types, int32_t must be two's complement.
>
> Perhaps checking for (INT_MIN + 1) == -0x7fffffff would avoid any
> possible problems?
#if INT_MIN == -2147483647-1
...
If you need to support non-two's-complement systems you might consider
something like:
#if INT_MIN == -2147483647-1
typedef int int32_t;
typedef int32_t signed32_t;
#elif INT_MIN == -2147483647-1
typedef int signed32_t;
...
#endif
The idea being that int32_t meets the strict C99/C11 requirements, while
signed32_t is a 32-bit signed type that might not be two's-complement,
which is probably good enough for most uses. You might also think about
padding bits. (Macros should be defined so you can tell which types
exist.)
In most contexts, assuming two's-complement probably isn't too bad, but
the assumption should at least be documented.
--
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 | Spiros Bousbouras <spibou@gmail.com> |
|---|---|
| Date | 2018-03-08 22:38 +0000 |
| Message-ID | <iXioC.128225$Q96.93220@fx45.am4> |
| In reply to | #127506 |
On Thu, 08 Mar 2018 13:55:17 -0800 Keith Thompson <kst-u@mib.org> wrote: > In most contexts, assuming two's-complement probably isn't too bad, but > the assumption should at least be documented. Even better to actually check. #define twos_complement ( (-1 & 3) == 3 ) #define ones_complement ( (-1 & 3) == 2 ) #define sign_and_magnitude ( (-1 & 3) == 1 ) #if !twos_complement # error This code can only work with two's complement representation. #endif
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-03-08 15:03 -0800 |
| Message-ID | <lny3j2cgqx.fsf@kst-u.example.com> |
| In reply to | #127511 |
Spiros Bousbouras <spibou@gmail.com> writes:
> On Thu, 08 Mar 2018 13:55:17 -0800
> Keith Thompson <kst-u@mib.org> wrote:
>> In most contexts, assuming two's-complement probably isn't too bad, but
>> the assumption should at least be documented.
>
> Even better to actually check.
>
> #define twos_complement ( (-1 & 3) == 3 )
> #define ones_complement ( (-1 & 3) == 2 )
> #define sign_and_magnitude ( (-1 & 3) == 1 )
>
> #if !twos_complement
> # error This code can only work with two's complement representation.
> #endif
It's not entirely clear to me, based on a quick reading of 6.10.1,
whether the evaluation is done using the semantics of the host or
target system. The standard specifically says that the values of
character constants might not match the target values, which can
matter if you have a cross-compiler for an EBCDIC-based target
running on an ASCII-based host system or vice versa.
It says that signed and unsigned integer types have the same
*representation* as intmax_t and uintmax_t, but that doesn't
necessarily imply that the semantics of bitwise operations are
the same.
If nothing else, you could do the test at run time at the top of main()
and abort the program if it's not two's-complement.
--
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 | Spiros Bousbouras <spibou@gmail.com> |
|---|---|
| Date | 2018-03-08 23:15 +0000 |
| Message-ID | <jujoC.229031$Nz7.165322@fx15.am4> |
| In reply to | #127515 |
On Thu, 08 Mar 2018 15:03:18 -0800 Keith Thompson <kst-u@mib.org> wrote: > Spiros Bousbouras <spibou@gmail.com> writes: > > On Thu, 08 Mar 2018 13:55:17 -0800 > > Keith Thompson <kst-u@mib.org> wrote: > >> In most contexts, assuming two's-complement probably isn't too bad, but > >> the assumption should at least be documented. > > > > Even better to actually check. > > > > #define twos_complement ( (-1 & 3) == 3 ) > > #define ones_complement ( (-1 & 3) == 2 ) > > #define sign_and_magnitude ( (-1 & 3) == 1 ) > > > > #if !twos_complement > > # error This code can only work with two's complement representation. > > #endif > > It's not entirely clear to me, based on a quick reading of 6.10.1, > whether the evaluation is done using the semantics of the host or > target system. Surely this is a matter of compiler options and documentation rather than something which would follow from the standard. > The standard specifically says that the values of > character constants might not match the target values, which can > matter if you have a cross-compiler for an EBCDIC-based target > running on an ASCII-based host system or vice versa. > > It says that signed and unsigned integer types have the same > *representation* as intmax_t and uintmax_t, but that doesn't > necessarily imply that the semantics of bitwise operations are > the same. Bitwise operations are done on a bit by bit basis , representation is irrelevant. > If nothing else, you could do the test at run time at the top of main() > and abort the program if it's not two's-complement. True.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2018-03-17 10:44 -0700 |
| Message-ID | <kfnvaduoauy.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #127515 |
Keith Thompson <kst-u@mib.org> writes: > Spiros Bousbouras <spibou@gmail.com> writes: > >> On Thu, 08 Mar 2018 13:55:17 -0800 >> Keith Thompson <kst-u@mib.org> wrote: >> >>> In most contexts, assuming two's-complement probably isn't too bad, but >>> the assumption should at least be documented. >> >> Even better to actually check. >> >> #define twos_complement ( (-1 & 3) == 3 ) >> #define ones_complement ( (-1 & 3) == 2 ) >> #define sign_and_magnitude ( (-1 & 3) == 1 ) >> >> #if !twos_complement >> # error This code can only work with two's complement representation. >> #endif > > It's not entirely clear to me, based on a quick reading of 6.10.1, > whether the evaluation is done using the semantics of the host or > target system. The standard specifically says that the values of > character constants might not match the target values, which can > matter if you have a cross-compiler for an EBCDIC-based target > running on an ASCII-based host system or vice versa. > > It says that signed and unsigned integer types have the same > *representation* as intmax_t and uintmax_t, but that doesn't > necessarily imply that the semantics of bitwise operations are > the same. Surely the statement that these types "act as if they have the same representation as" intmax_t or uintmax_t is meant to signify that the _value_ representations are the same. Having _object_ representations be the same would be meaningless and pointless. If the value representations are the same, then how they behave with respect to bitwise operations must be the same.
[toc] | [prev] | [next] | [standalone]
| From | Steven Petruzzellis <frelwizzen@gmail.com> |
|---|---|
| Date | 2018-03-18 03:47 -0700 |
| Message-ID | <109cde3d-ca27-44b8-9cbc-4dfb0aadc9ed@googlegroups.com> |
| In reply to | #127951 |
On Saturday, March 17, 2018 at 10:44:47 AM UTC-7, Tim Rentsch wrote: > Keith Thompson <kst-u@mib.org> writes: > > > Spiros Bousbouras <spibou@gmail.com> writes: > > > >> On Thu, 08 Mar 2018 13:55:17 -0800 > >> Keith Thompson <kst-u@mib.org> wrote: > >> > >>> In most contexts, assuming two's-complement probably isn't too bad, but > >>> the assumption should at least be documented. > >> > >> Even better to actually check. > >> > >> #define twos_complement ( (-1 & 3) == 3 ) > >> #define ones_complement ( (-1 & 3) == 2 ) > >> #define sign_and_magnitude ( (-1 & 3) == 1 ) > >> > >> #if !twos_complement > >> # error This code can only work with two's complement representation. > >> #endif > > > > It's not entirely clear to me, based on a quick reading of 6.10.1, > > whether the evaluation is done using the semantics of the host or > > target system. The standard specifically says that the values of > > character constants might not match the target values, which can > > matter if you have a cross-compiler for an EBCDIC-based target > > running on an ASCII-based host system or vice versa. > > > > It says that signed and unsigned integer types have the same > > *representation* as intmax_t and uintmax_t, but that doesn't > > necessarily imply that the semantics of bitwise operations are > > the same. > > Surely the statement that these types "act as if they have the > same representation as" intmax_t or uintmax_t is meant to signify > that the _value_ representations are the same. Having _object_ > representations be the same would be meaningless and pointless. > If the value representations are the same, then how they behave > with respect to bitwise operations must be the same. Enough already. You're again trying to bolster yourself beyond your grade. You're the court jester and your many incoherent programs show this. A constant, relentless, posting itch, while suffering from an empty mind - fundamentally slippery Rob 'The Shill' Speed camp followers, and satisfactorily-waxed fish, hung from the ceiling for his own individual requirements. If Rob 'The Shill' Speed calls getting his ass kicked hard like an idiot day in and day out by Autumn Nissen and me successful 'trolling', then whatever... he is a splendid troll. I can not subscribe to that view, I use another term. I call Rob 'The Shill' Speed a total jackass. Until Rob 'The Shill' Speed offers up his 'more advanced' Mac quick fix for appraisal, there is no challenge, just wild assertions. Requesting Rob 'The Shill' Speed to admit guilt, which I have done, is different than showing his deceit. My argument was that good people arrive here to catch aberrant behavior. It isn't as if most don't know what this forum is, Autumn Nissen especially. Ha, ha! Can UTF-8 characters be concatenated into a string with a logical connection to the "real" world; that is the question posed recently by those astonished at the non-stop flood of gibberish from trolls and Cheetos smelling losers. -- One Smart Penny! https://groups.google.com/forum/#!topic/comp.sys.mac.advocacy/RSikBcWxBLo https://groups.google.com/forum/#!topic/comp.os.linux.advocacy/tzMH39QmAmU https://groups.google.com/forum/#!topic/alt.os.linux/BVpdH5KOc6s Jonas Eklundh Communication
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2018-03-09 10:10 +0100 |
| Message-ID | <p7tj2b$k5c$1@dont-email.me> |
| In reply to | #127506 |
On 08/03/18 22:55, Keith Thompson wrote: > David Brown <david.brown@hesbynett.no> writes: >> On 08/03/18 18:58, Keith Thompson wrote: >>> David Brown <david.brown@hesbynett.no> writes: >>> [...] >>>> And then name one where you could not do this to get valid int32_t and >>>> uint32_t types: >>>> >>>> #include <limits.h> >>>> >>>> #if INT_MIN == -2147483647 >>>> typedef int int32_t; >>>> typedef unsigned int uint32_t; >>>> #elif LONG_MIN == -2147483647 >>>> typedef long int int32_t; >>>> typedef unsigned long int uint32_t; >>>> #elif SCHAR_MIN == -2147483647 >>>> typedef signed char int32_t; >>>> typedef unsigned char uint32_t; >>>> #else >>>> #error No support for 32-bit sized types >>>> #endif >>> >>> You mean -2147483648, not -2147483647. And the expression -2147483648 >>> can be problematic. I'd check the value of INT_MAX (and I'd likely use >>> 0x7fffffff because it's easier to see typos). >>> >> >> Yes, I meant -2147483648 - and yes, hex is easier in this case. >> >> But I did mean to check INT_MIN rather than INT_MAX - because (as far as >> I can see) that check will also ensure that the representation is two's >> complement and not one's complement or sign magnitude (which could have >> INT_MAX equal to 2147483647 and INT_MIN equal to -2147483647). For C99 >> compatible int32_t and uint32_t types, int32_t must be two's complement. >> >> Perhaps checking for (INT_MIN + 1) == -0x7fffffff would avoid any >> possible problems? > > #if INT_MIN == -2147483647-1 > ... > > If you need to support non-two's-complement systems you might consider > something like: > > #if INT_MIN == -2147483647-1 > typedef int int32_t; > typedef int32_t signed32_t; > #elif INT_MIN == -2147483647-1 Should that not be: #elif INT_MIN == -2147483647 ? > typedef int signed32_t; > ... > #endif > > The idea being that int32_t meets the strict C99/C11 requirements, while > signed32_t is a 32-bit signed type that might not be two's-complement, > which is probably good enough for most uses. You might also think about > padding bits. (Macros should be defined so you can tell which types > exist.) > > In most contexts, assuming two's-complement probably isn't too bad, but > the assumption should at least be documented. > I would be inclined to just have the two's complement test, and if that fails halt with an #error. Failure to compile is vastly better than compiling with silent errors, and systems that are not two's complement are rare as hens' teeth. In practice, for my own code I simple use <stdint.h> and use the standard types like int32_t. To my mind, that is documentation enough that the code assumes two's complement representation. I only come across the need to create user-level types like this when working with libraries designed to work with a range of embedded systems, and there you generally have some headers or configuration files for matching to the target processor, microcontroller and/or compiler. These will often contain many other bits and pieces of non-portable or implementation-dependent code in macros, typedefs and other definitions - defining types like "i32" are just one part of this.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-03-09 10:10 -0800 |
| Message-ID | <lnina5ce6v.fsf@kst-u.example.com> |
| In reply to | #127529 |
David Brown <david.brown@hesbynett.no> writes:
> On 08/03/18 22:55, Keith Thompson wrote:
[...]
>> If you need to support non-two's-complement systems you might consider
>> something like:
>>
>> #if INT_MIN == -2147483647-1
>> typedef int int32_t;
>> typedef int32_t signed32_t;
>> #elif INT_MIN == -2147483647-1
>
> Should that not be:
>
> #elif INT_MIN == -2147483647
>
> ?
Yes thanks.
>
>> typedef int signed32_t;
>> ...
>> #endif
[...]
--
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 | jameskuyper@verizon.net |
|---|---|
| Date | 2018-03-08 14:21 -0800 |
| Message-ID | <bf8ebc4b-1b0a-4213-a7c8-dd92f71874b5@googlegroups.com> |
| In reply to | #127500 |
On Thursday, March 8, 2018 at 4:03:25 PM UTC-5, David Brown wrote: > On 08/03/18 18:58, Keith Thompson wrote: > > David Brown <david.brown@hesbynett.no> writes: > > [...] > >> And then name one where you could not do this to get valid int32_t and > >> uint32_t types: > >> > >> #include <limits.h> > >> > >> #if INT_MIN == -2147483647 > >> typedef int int32_t; > >> typedef unsigned int uint32_t; > >> #elif LONG_MIN == -2147483647 > >> typedef long int int32_t; > >> typedef unsigned long int uint32_t; > >> #elif SCHAR_MIN == -2147483647 > >> typedef signed char int32_t; > >> typedef unsigned char uint32_t; > >> #else > >> #error No support for 32-bit sized types > >> #endif > > > > You mean -2147483648, not -2147483647. And the expression -2147483648 > > can be problematic. I'd check the value of INT_MAX (and I'd likely use > > 0x7fffffff because it's easier to see typos). > > > > Yes, I meant -2147483648 - and yes, hex is easier in this case. > > But I did mean to check INT_MIN rather than INT_MAX - because (as far as > I can see) that check will also ensure that the representation is two's > complement and not one's complement or sign magnitude (which could have > INT_MAX equal to 2147483647 and INT_MIN equal to -2147483647). For C99 > compatible int32_t and uint32_t types, int32_t must be two's complement. Note: a fully conforming implementation of C is allowed to use a two’s complement representation for a signed integer type, for which "the value with sign bit 1 and all value bits zero" is a trap representation (6.2.6.2p2). For a 32-bit two's complement type, that would result in INT_MIN == -2147483647. Of course, trap representations are also prohibited for the size-named types, so that's fine. > Perhaps checking for (INT_MIN + 1) == -0x7fffffff would avoid any > possible problems? Decimal constants have signed type unless explicitly terminated with a U or u. Octal and hexadecimal constants, on the other hand, can have either signed or unsigned types, depending upon the values of the corresponding *_MAX macros (6.4.4.1p4). For instance, that constant will have the type "unsigned int" if INT_MAX < 0x7fffffff && 0x7fffffff <= UINT_MAX - an unlikely combination on any real world machine, but permissible for a fully conforming implementation of C. If UINT_MAX == 0x7fffffff, the expression -0x7fffffff would have a value of 0x1. Now, I can't see any way for your conditions to produce incorrect results due to that fact, but I think that, in general, you should use only decimal constants whenever it's important that a constant be signed, and use a U suffix when it's important that it be unsigned.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-03-08 15:10 -0800 |
| Message-ID | <lntvtqcgfg.fsf@kst-u.example.com> |
| In reply to | #127507 |
jameskuyper@verizon.net writes:
> On Thursday, March 8, 2018 at 4:03:25 PM UTC-5, David Brown wrote:
[...]
>> Perhaps checking for (INT_MIN + 1) == -0x7fffffff would avoid any
>> possible problems?
>
> Decimal constants have signed type unless explicitly terminated with a
> U or u. Octal and hexadecimal constants, on the other hand, can have
> either signed or unsigned types, depending upon the values of the
> corresponding *_MAX macros (6.4.4.1p4). For instance, that constant will
> have the type "unsigned int" if
> INT_MAX < 0x7fffffff && 0x7fffffff <= UINT_MAX - an unlikely combination
> on any real world machine, but permissible for a fully conforming
> implementation of C. If UINT_MAX == 0x7fffffff, the expression
> -0x7fffffff would have a value of 0x1.
For preprocessor arithmetic, signed and unsigned integer types are
treated as having the same representation as intmax_t and uintmax_t,
respectively, so they're at least 64 bits. 0x7fffffff, if it's
evaluated in a #if, has a type we might call "preprocessor-int", which
is at least 64 bits and guaranteed to be signed.
For example, this:
#include <stdio.h>
int main(void) {
#if 0xF0000000 < -1
puts("0xF0000000 < -1");
#else
puts("0xF0000000 >= -1");
#endif
if (0xF0000000 < -1) {
puts("0xF0000000 < -1");
}
else {
puts("0xF0000000 >= -1");
}
}
prints:
0xF0000000 >= -1
0xF0000000 < -1
> Now, I can't see any way for your conditions to produce incorrect
> results due to that fact, but I think that, in general, you should use
> only decimal constants whenever it's important that a constant be signed,
> and use a U suffix when it's important that it be unsigned.
--
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 | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2018-03-09 10:13 +0100 |
| Message-ID | <p7tj81$lag$1@dont-email.me> |
| In reply to | #127516 |
On 09/03/18 00:10, Keith Thompson wrote: > jameskuyper@verizon.net writes: >> On Thursday, March 8, 2018 at 4:03:25 PM UTC-5, David Brown wrote: > [...] >>> Perhaps checking for (INT_MIN + 1) == -0x7fffffff would avoid any >>> possible problems? >> >> Decimal constants have signed type unless explicitly terminated with a >> U or u. Octal and hexadecimal constants, on the other hand, can have >> either signed or unsigned types, depending upon the values of the >> corresponding *_MAX macros (6.4.4.1p4). For instance, that constant will >> have the type "unsigned int" if >> INT_MAX < 0x7fffffff && 0x7fffffff <= UINT_MAX - an unlikely combination >> on any real world machine, but permissible for a fully conforming >> implementation of C. If UINT_MAX == 0x7fffffff, the expression >> -0x7fffffff would have a value of 0x1. > > For preprocessor arithmetic, signed and unsigned integer types are > treated as having the same representation as intmax_t and uintmax_t, > respectively, so they're at least 64 bits. That applies to C99 (and C11), but not C90 which does not have intmax_t and uintmax_t (assuming I remember correctly - I don't have C90 open at the moment). And if we have C99 (or C11), we can just use int32_t and be happy!
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-03-09 10:10 -0800 |
| Message-ID | <lnmuzhce81.fsf@kst-u.example.com> |
| In reply to | #127530 |
David Brown <david.brown@hesbynett.no> writes:
> On 09/03/18 00:10, Keith Thompson wrote:
>> jameskuyper@verizon.net writes:
>>> On Thursday, March 8, 2018 at 4:03:25 PM UTC-5, David Brown wrote:
>> [...]
>>>> Perhaps checking for (INT_MIN + 1) == -0x7fffffff would avoid any
>>>> possible problems?
>>>
>>> Decimal constants have signed type unless explicitly terminated with a
>>> U or u. Octal and hexadecimal constants, on the other hand, can have
>>> either signed or unsigned types, depending upon the values of the
>>> corresponding *_MAX macros (6.4.4.1p4). For instance, that constant will
>>> have the type "unsigned int" if
>>> INT_MAX < 0x7fffffff && 0x7fffffff <= UINT_MAX - an unlikely combination
>>> on any real world machine, but permissible for a fully conforming
>>> implementation of C. If UINT_MAX == 0x7fffffff, the expression
>>> -0x7fffffff would have a value of 0x1.
>>
>> For preprocessor arithmetic, signed and unsigned integer types are
>> treated as having the same representation as intmax_t and uintmax_t,
>> respectively, so they're at least 64 bits.
>
> That applies to C99 (and C11), but not C90 which does not have intmax_t
> and uintmax_t (assuming I remember correctly - I don't have C90 open at
> the moment). And if we have C99 (or C11), we can just use int32_t and
> be happy!
In C90:
The resulting tokens comprise the controlling constant expression
which is evaluated according to the rules of 6.4 using arithmetic
that has at least the ranges specified in 5.2.4.2, except that int
and unsigned int act as if they have the same representation as,
respectively, long and unsigned long.
(C90 didn't have intmax_t and uintmax_t, but if it did it presumably
would have defined them as long and unsigned 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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2018-03-08 10:28 +0100 |
| Message-ID | <p7qvnq$n21$1@dont-email.me> |
| In reply to | #127447 |
On 07/03/18 20:12, supercat@casperkitty.com wrote: > On Wednesday, March 7, 2018 at 12:11:15 PM UTC-6, Keith Thompson wrote: >> supercat@casperkitty.com writes: >> [...] >>> If instead a program can be designed so that it will work with any common >>> microprocessor platform where char, short, and long are 8, 16, and 32 bits, >>> respectively, are consistently big-endian or little-endian, and allow such >>> representation to be accessed using lvalues of any integer type which are >>> visibly derived in the context where they are used, and if such code >>> requires that either BIG_ENDIAN or LITTLE_ENDIAN be pre-declared, then >>> the code could be expected to be usable on any development system meeting >>> those requirements without having to be tested on every single one of them. >> >> Consider. Writing. Shorter. Sentences. >> >> Any program that assumes 32-bit long will fail on many of the systems I >> use, where long is 64 bits. How about writing code that doesn't assume >> how wide long is? > > A lot of code was written before C99 added int32_t and uint32_t as > standards. The closest things to standard 32-bit type were "long" and > "unsigned long", and an assumption that "long" would be 32 bits was > about as portable as an assumption that "char" would be eight. A > machine with 36-bit words wouldn't have a 32-bit long, but it wouldn't > have an 8-bit "char" either. It is decades since 64-bit computing has been mainstream - MIPS, Alpha, SPARC, PPC have all had it for about 25 years or so. And "long" has invariably been 64-bit on these systems. Note that these all pre-date C99, and pre-date "long long" - a 64-bit processor would be pretty useless without a 64-bit type. It is /only/ x86-64 Windows that has a 64-bit processor and 32-bit "long". "long" is almost invariably 32-bit on 8-bit, 16-bit and 32-bit processors. And these are the processor sizes that dominated until recently. Also, "long" is always /at least/ 32-bit. So certainly "long" has always been a popular choice for a typedef for a 32-bit type. But an /assumption/ that "long" is always 32-bit has never been a good idea, and has not been justifiable for many years. Even when using tools that did not support C99, it was common to have a <stdint.h> or compiler-specific header with known sizes. And when those were not available, it was common to use application-specific fixed-size typedefs. If you get a library, RTOS, or other block of code that is designed to be somewhat portable but supports C90, and it needs a specific 32-bit type (or other specific sizes), you will usually find that it has typedefs for these types - either automatically defined based on <limits.h>, or with detection for a number of compilers, or as a user-modified configuration header. > > Further, a program could provide users of platforms where e.g. "int" is > 32 bits but "long" is bigger with instructions for how to deal with that, > e.g. by starting with > > #ifndef I32_TYPE > #define I32_TYPE long > #endif > #ifndef U32_TYPE > #define U32_TYPE unsigned long > #endif > > and instructing users of such platforms to predefine "I32_TYPE" as a macro > which describes a signed 32-bit type, and U32_TYPE as a macro which describes > an unsigned 32-bit type. Users of more common implementations wouldn't have > to worry about defining such macros. That is fine - /if/ it is clear in the documentation for the code. But it is far better (and very simple) to have compile-time checks that the settings for these types are correct. > >> No conforming implementation can predefine BIG_ENDIAN or LITTLE_ENDIAN. > > Most quality implementations can easily be configured for a non-conforming > mode in which such symbols are defined, using a command-line option like > "-dBIG_ENDIAN". Alternatively, code could be shipped with an essentially- > empty "opts.h" file which is the first thing included by each other file, > and which could be edited if necessary to pre-define any macros needed > elsewhere. As Keith said, no conforming implementation can predefine these symbols. They are not reserved names, and user code could use them. Predefined symbols such as __BIG_ENDIAN__ or _LITTLE_ENDIAN would be fine, and just as useful. Why are you arguing against such an obvious point? Most compilers - at least those which support more than one target - have something like that already. > >> And most code doesn't need to care about endianness. I wouldn't mind >> having a way to determine the current system's endianness, (maybe >> something in <limits.h>), but it's not a huge deal. I think if it were to be added, it would make sense to have a new header and to include functions for swapping endianness or otherwise manipulating data in endianness-specific ways. When code needs to know the endianness of a platform, it is often in order to create such functions - so having them in the header file would be convenient. The challenge would be for targets that are not pure little-endian or pure big-endian. I expect this would need to be an optional feature. But as you say, it is not a big deal. > > It can be important for code that handles things like encryption, big-number > math, CRC calculations, etc. Not the most common usages, but not ones that > should be totally ignored either. > > On the other hand, before anything like that could be added to limits.h in > any standard way, there would first have to be agreement that there are > four common ways of associated the bits of a "uint32_t" with the bits of > the underlying bytes, and that the other (32!-4) mappings are sufficiently > unusual as to justify lumping them into an "other" category. >
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-03-08 10:28 -0800 |
| Message-ID | <f9079c41-514f-4309-b5cd-6ed16b8111f9@googlegroups.com> |
| In reply to | #127463 |
On Thursday, March 8, 2018 at 3:28:38 AM UTC-6, David Brown wrote:
> It is decades since 64-bit computing has been mainstream - MIPS, Alpha,
> SPARC, PPC have all had it for about 25 years or so. And "long" has
> invariably been 64-bit on these systems. Note that these all pre-date
> C99, and pre-date "long long" - a 64-bit processor would be pretty
> useless without a 64-bit type.
>
> It is /only/ x86-64 Windows that has a 64-bit processor and 32-bit "long".
The vast majority of microcontrollers used in embedded systems use a
32-bit "long", and a substantial fraction use 16-bit "int". Is there any
reason why a 64-bit processor system should not be able to use code written
for a smaller micro?
> "long" is almost invariably 32-bit on 8-bit, 16-bit and 32-bit
> processors. And these are the processor sizes that dominated until
> recently. Also, "long" is always /at least/ 32-bit. So certainly
> "long" has always been a popular choice for a typedef for a 32-bit type.
>
> But an /assumption/ that "long" is always 32-bit has never been a good
> idea, and has not been justifiable for many years. Even when using
> tools that did not support C99, it was common to have a <stdint.h> or
> compiler-specific header with known sizes. And when those were not
> available, it was common to use application-specific fixed-size
> typedefs. If you get a library, RTOS, or other block of code that is
> designed to be somewhat portable but supports C90, and it needs a
> specific 32-bit type (or other specific sizes), you will usually find
> that it has typedefs for these types - either automatically defined
> based on <limits.h>, or with detection for a number of compilers, or as
> a user-modified configuration header.
No platform should have any particular difficulty supporting code that
calls printf-style functions with "%d" for 8-bit and 16-bit types, "%ld"
for 32-bit types, and "%lld" for 64-bit types. While the Standard
provides macros like PRId32, code using them is often significantly less
legible than code written using the above strings.
The most readable way of outputting a value of a type uint32_t would probably
be to use "%lu" and then coerce or convert the value to an unsigned long,
but that seems unnecessarily clunky. Further, accidental failure to convert
or coerce the value would yield code that would work on platforms where
"long" is 32 bits, and would often work on many platforms where it is 64
bits, but which would not be reliable on all 64-bit platforms. Not a good
combination.
> > Further, a program could provide users of platforms where e.g. "int" is
> > 32 bits but "long" is bigger with instructions for how to deal with that,
> > e.g. by starting with
> >
> > #ifndef I32_TYPE
> > #define I32_TYPE long
> > #endif
> > #ifndef U32_TYPE
> > #define U32_TYPE unsigned long
> > #endif
> >
> > and instructing users of such platforms to predefine "I32_TYPE" as a macro
> > which describes a signed 32-bit type, and U32_TYPE as a macro which describes
> > an unsigned 32-bit type. Users of more common implementations wouldn't have
> > to worry about defining such macros.
>
> That is fine - /if/ it is clear in the documentation for the code. But
> it is far better (and very simple) to have compile-time checks that the
> settings for these types are correct.
Such compile-time checks could be included as well. The point is that if
the code is being run on a platform that defines things in suitable fashion
there should be no need for the compiler operator to take any manual action
to configure the types.
> >> No conforming implementation can predefine BIG_ENDIAN or LITTLE_ENDIAN.
> >
> > Most quality implementations can easily be configured for a non-conforming
> > mode in which such symbols are defined, using a command-line option like
> > "-dBIG_ENDIAN". Alternatively, code could be shipped with an essentially-
> > empty "opts.h" file which is the first thing included by each other file,
> > and which could be edited if necessary to pre-define any macros needed
> > elsewhere.
>
> As Keith said, no conforming implementation can predefine these symbols.
> They are not reserved names, and user code could use them. Predefined
> symbols such as __BIG_ENDIAN__ or _LITTLE_ENDIAN would be fine, and just
> as useful. Why are you arguing against such an obvious point?
If the code were to check whether __BIG_ENDIAN is defined, and then the
Standard were to specify that little-endian implementations should define
__BIG_ENDIAN with a value of 0, such code would need to be modified to
make it usable with compilers implementing the new standard. The name is
used without underscores because its meaning and purpose are defined by
user code rather than the Standard or implementation.
> Most compilers - at least those which support more than one target -
> have something like that already.
Some might, but they might not define such things consistently. If one
vendor might decides that a little-endian compilers should behave as though
code started with
#define __LITTLE_ENDIAN
#undef __BIG_ENDIAN
while another vendor might decide that the definitions should be equivalent to
#define __LITTLE_ENDIAN 1
#define __BIG_ENDIAN 0
and another might decide the proper labeling is
#undef __LITTLE_ENDIAN // Code should use value of __BIG_ENDIAN
#define __BIG_ENDIAN 0
How should a programmer be expected to write code that could work with any
plausible means via which an implementation might define such symbols,
if the programmer doesn't know in advance which implementation will be used?
> >> And most code doesn't need to care about endianness. I wouldn't mind
> >> having a way to determine the current system's endianness, (maybe
> >> something in <limits.h>), but it's not a huge deal.
>
> I think if it were to be added, it would make sense to have a new header
> and to include functions for swapping endianness or otherwise
> manipulating data in endianness-specific ways. When code needs to know
> the endianness of a platform, it is often in order to create such
> functions - so having them in the header file would be convenient. The
> challenge would be for targets that are not pure little-endian or pure
> big-endian. I expect this would need to be an optional feature.
I believe I've advocated for such functions. If such functions were
standard, an implementation could process them as efficient intrinsics
much more easily than it could recognize all of the combinations of
shifts and other operations user code might employ to do the same thing.
[toc] | [prev] | [next] | [standalone]
Page 5 of 6 — ← Prev page 1 2 3 4 [5] 6 Next page →
Back to top | Article view | comp.lang.c
csiph-web