Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Compiling and linking code from different places in the file system Date: Thu, 08 Mar 2018 13:26:38 -0800 Organization: None to speak of Lines: 104 Message-ID: References: <6oSnC.178019$eQ7.108635@fx46.am4> <87o9k055d2.fsf@bsb.me.uk> <13a67039-e46b-4337-a1a3-058210e55b6e@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="d5db3c990c5a8317a11173691196aced"; logging-data="24090"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX194wiOcs+IKcP3fEHZPDRgv" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:qkQGDSPsUiZxOjrQuK3GFpy1OCk= sha1:DX/NGa9ZSvsmNR7vwptAClp2Wno= Xref: csiph.com comp.lang.c:127503 supercat@casperkitty.com writes: > 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? Code not designed to be portable might fail, and there are sometimes good reasons to write non-portable code. Code written to be portable, if that's done successfully, should work on either 32-bit or 64-bit systems. Code written to assume that long is exactly 32 bits, **which is what you suggested upthread**, would obviously fail on an implementation where long is 64 bits. Did you mean to suggest that code should assume long is exactly 32 bits? I've restated that interpretation of your words several times, and you haven't corrected it. [...] > 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. "%d" is for int, and for narrower types that promote to int. "%ld" with a 32-bit argument has undefined behavior, and will likely fail, on a system where long is 64 bits, and as you know such systems are common. Here's a radical idea: Use the right format for the type you're printing. If you're not sure what it is, convert the argument to a type for which you know the right format. There is no other correct solution, unless you design a new output system. > 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. It works. Yes, omitting the cast can cause problems. >> > 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. int32_t and uint32_t exist. You almost certainly don't need to reinvent them. If you do, that work has already been done (I provided a link upthread). [...] > 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. You want the standard to define a way, probably using predefined macros, for an application to find the endianess (big-endian, little-endian, or other) of the current platform. Does anything more than that need to be said? -- Keith Thompson (The_Other_Keith) kst-u@mib.org 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"