Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to specify an 8 byte bool ?

91 views
Skip to first unread message

Lynn McGuire

unread,
Oct 4, 2022, 9:41:22 PM10/4/22
to
How do I specify an 8 byte bool ? Long long ?

Thanks,
Lynn

Keith Thompson

unread,
Oct 4, 2022, 10:58:56 PM10/4/22
to
Lynn McGuire <lynnmc...@gmail.com> writes:
> How do I specify an 8 byte bool ? Long long ?

What for?

bool is a predefined type, and its size is determined by the implementation.

long long is at least 64 bits (and almost always exactly 64 bits).
uint64_t and int64_t are exactly 64 bits, but are not guaranteed to
exist. A "byte" is almost always 8 bits, but may be larger (see
CHAR_BIT).

What problem are you trying to solve?

--
Keith Thompson (The_Other_Keith) Keith.S.T...@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

Lynn McGuire

unread,
Oct 4, 2022, 11:35:29 PM10/4/22
to
On 10/4/2022 9:58 PM, Keith Thompson wrote:
> Lynn McGuire <lynnmc...@gmail.com> writes:
>> How do I specify an 8 byte bool ? Long long ?
>
> What for?
>
> bool is a predefined type, and its size is determined by the implementation.
>
> long long is at least 64 bits (and almost always exactly 64 bits).
> uint64_t and int64_t are exactly 64 bits, but are not guaranteed to
> exist. A "byte" is almost always 8 bits, but may be larger (see
> CHAR_BIT).
>
> What problem are you trying to solve?

I've got a double array, integer*8 array, logical*8 array, and
character*8 array equivalenced in my Fortran code that I am converting
to C++. I want to have the same capability in my C++ code until I get
down the road and figure out what I want to do with this code, if anything.

Thanks,
Lynn

Christian Gollwitzer

unread,
Oct 5, 2022, 1:40:57 AM10/5/22
to
Am 05.10.22 um 05:35 schrieb Lynn McGuire:
Then I'd use uint64_t for the logical, int64_t for the integer and
char[8] for the character array (not sure about the last one, though,
since I don't use Fortran much). You can also check how the old f2c
converter compiles it (https://netlib.org/f2c/). It generally works well
for F77 code, although the output is not overly readable.
I guess you used fable instead of f2c because you want to work on the
code after translation, right?

Christian

David Brown

unread,
Oct 5, 2022, 3:39:15 AM10/5/22
to
I don't know Fortran, but if you want something that works like a bool
and takes 8 bytes, you can either use a uint64_t and be careful that you
don't put anything other than 0 or 1 in it (that might be fine when you
have automatically generated code).

Alternatively, it's easy to make a class that acts like a bool:

(Adding concepts to limit the type of T is left as an exercise for the
reader :-) )


#include <cstdint>

template <class T>
class sized_bool {
private :
T storage;
public :
constexpr sized_bool() : storage(0) {}
constexpr sized_bool(bool b) : storage(b) {}
constexpr operator bool() const { return storage; }
};

using big_bool = sized_bool<std::uint64_t>;

void tests() {
static_assert(sizeof(big_bool) == 8);

constexpr big_bool b1 = 1;
static_assert(b1 == true);
static_assert(b1 == 1);
static_assert(b1 ? 1 : 0);

constexpr big_bool b2 { false };
static_assert(b2 == false);
static_assert(b2 == 0);
static_assert(b2 ? 0 : 1);

constexpr big_bool b3 = 123;
static_assert(b3 == true);
static_assert(b3 == 1);
static_assert(b3 ? 1 : 0);

static_assert(big_bool(100) == 1);
}

Lynn McGuire

unread,
Oct 5, 2022, 3:02:46 PM10/5/22
to
I am building my own version of f2c with significant code from fable.
Fable is written in python and is part of another app so separating it
out is a "Hot Skillz". F2c is written in very nasty plain old C code.

Here is my task list for f2c to date:

// 1. added support for a .cpp output file instead of just the .c file
// 2. convert the F90 cycle command to the C continue
// 3. convert the F90 exit command to the C break
// 4. convert the c /* comment */ to // comment
// 5. added support for the logical*8 data type, complementary to the
integer*8
// data type for memory alignment, both resolve to the C long long
integer
// 6. generate true and false for logicals if C++ instead of TRUE_ and
FALSE_
// 7. removed all trailing underscores from variable and subroutine names
// 8. removed the ftnlen argument from the calls to subroutines with
character arguements
// 9. added the Fabel FEM library


// Things to do:
// 1. make all argument arrays start at index 0
// 2. convert writes to the FEM single command write with embedded format
// 3. retain array lengths
// 4. retain parameters with their values

Lynn

Lynn McGuire

unread,
Oct 5, 2022, 3:04:02 PM10/5/22
to
On 10/5/2022 12:38 AM, Christian Gollwitzer wrote:
BTW, thanks !

Lynn

Lynn McGuire

unread,
Oct 5, 2022, 3:04:13 PM10/5/22
to
Thanks !

Lynn


Lynn McGuire

unread,
Oct 5, 2022, 3:10:53 PM10/5/22
to
I forgot to mention that this is how I handle the 8 byte logical*8 right
now:

typedef long long logical8;

Thanks,
Lynn


Scott Lurndal

unread,
Oct 5, 2022, 4:34:46 PM10/5/22
to
Wouldn't it make more sense to convert to LOGICAL*4 or just LOGICAL and
use a byte-width C++ bool instead? Seems silly to waste 63 bits.

Lynn McGuire

unread,
Oct 5, 2022, 5:19:16 PM10/5/22
to
The indexes for the arrays are the same value for all four types of
arrays. So every array chunk has to be 64 bits whether it is double,
integer*8, character*8, or logical*8.

And yes, I agree, not efficient. But, who cares in this day of TB
drives and GB ram ? And I want to use the same code base for the 32 bit
version and the 64 bit version.

Thanks,
Lynn

Fred. Zwarts

unread,
Oct 5, 2022, 5:20:09 PM10/5/22
to
Op 05.okt..2022 om 05:35 schreef Lynn McGuire:
The Fortran EQUIVALENT is in my mind roughly equivalent to a C++ union.
So, I would probably go for an array of unions. Where each union is a
union of a double, integer, bool and char[8]. The bool would then
automatically use the space of the largest type in the union.


Scott Lurndal

unread,
Oct 5, 2022, 6:26:15 PM10/5/22
to
Lynn McGuire <lynnmc...@gmail.com> writes:
>On 10/5/2022 3:34 PM, Scott Lurndal wrote:
>> Lynn McGuire <lynnmc...@gmail.com> writes:
>>> On 10/4/2022 8:41 PM, Lynn McGuire wrote:
>>>> How do I specify an 8 byte bool ?  Long long ?
>>>>
>>>> Thanks,
>>>> Lynn
>>>
>>> I forgot to mention that this is how I handle the 8 byte logical*8 right
>>> now:
>>>
>>> typedef long long logical8;
>>
>> Wouldn't it make more sense to convert to LOGICAL*4 or just LOGICAL and
>> use a byte-width C++ bool instead? Seems silly to waste 63 bits.
>
>The indexes for the arrays are the same value for all four types of
>arrays. So every array chunk has to be 64 bits whether it is double,
>integer*8, character*8, or logical*8.

Presumably the compiler will do the appropriate math using
the index to calculate the memory byte(s) required.

I don't understand your comment, unless you're using byte offsets
intead of normal fortran indexing.

Scott Lurndal

unread,
Oct 5, 2022, 6:27:47 PM10/5/22
to
Ah never mind, I see your aliasing the same storage four ways.

Lynn McGuire

unread,
Oct 5, 2022, 8:16:43 PM10/5/22
to
Yup.

Thanks,
Lynn

daniel...@gmail.com

unread,
Oct 5, 2022, 9:45:54 PM10/5/22
to
On Wednesday, October 5, 2022 at 5:20:09 PM UTC-4, F.Zwarts wrote:
> Op 05.okt..2022 om 05:35 schreef Lynn McGuire:

> > I've got a double array, integer*8 array, logical*8 array, and
> > character*8 array equivalenced in my Fortran code that I am converting
> > to C++. I want to have the same capability in my C++ code until I get
> > down the road and figure out what I want to do with this code, if anything.
> The Fortran EQUIVALENT is in my mind roughly equivalent to a C++ union.

> So, I would probably go for an array of unions. Where each union is a
> union of a double, integer, bool and char[8]. The bool would then
> automatically use the space of the largest type in the union.

I think it would be undefined behaviour to use a C++ union for a FORTRAN
EQUIVALENCE statement. C++ (unlike C) does not permit type pruning.

Daniel

Lynn McGuire

unread,
Oct 5, 2022, 10:05:48 PM10/5/22
to
I assume that you mean type punning ???
https://en.wikipedia.org/wiki/Type_punning

Lynn


daniel...@gmail.com

unread,
Oct 5, 2022, 10:07:32 PM10/5/22
to
On Wednesday, October 5, 2022 at 10:05:48 PM UTC-4, Lynn McGuire wrote:
> I assume that you mean type punning ???
> https://en.wikipedia.org/wiki/Type_punning
>
> Lynn

Just so :-(

Daniel

Fred. Zwarts

unread,
Oct 6, 2022, 4:40:51 AM10/6/22
to
Op 06.okt..2022 om 03:45 schreef daniel...@gmail.com:
I did not read that type punning was used in this Fortran program.

David Brown

unread,
Oct 6, 2022, 8:14:39 AM10/6/22
to
I think "type pruning" sounds more fun than mere "type punning". It
sounds like a way to clear up a mess of too many types, leaving only the
pretty ones :-)

I guess the answer here is a class which has a single storage unit
(uint64_t) with constructors and conversion operators to the different
types, using memcpy() to make it all legal. A decent compiler will
optimise away the memcpy().

Alternatively, if you can limit yourself to gcc, clang, icc, and other
compilers that copy gcc's attributes, the "may_alias" attribute on a
type lets you use it for type punning (it gives the type the superpowers
of a character type for accesses).

#include <cstdint>
#include <cstring>
#include <array>

class DIBC {
private :
uint64_t storage;
template <class T> constexpr uint64_t toUint64_t(const T x) {
static_assert(sizeof(x) == 8);
uint64_t y;
std::memcpy(&y, &x, 8);
return y;
}
template <class T> constexpr T fromUint64_t(uint64_t x) {
static_assert(sizeof(T) == 8);
T y;
std::memcpy(&y, &x, 8);
return y;
}
public :
using char8 = std::array<char, 8>;
constexpr DIBC() : storage(0) {}
constexpr DIBC(uint64_t x) : storage(x) {}
constexpr DIBC(int64_t x) : storage(x) {}
constexpr DIBC(bool x) : storage(x) {}
constexpr DIBC(char8 x) : storage(toUint64_t(x)) {}

constexpr operator uint64_t() const { return storage; }
constexpr operator int64_t() const { return storage; }
constexpr operator bool() const { return storage; }
constexpr operator char8 const () { return
fromUint64_t<char8>(storage); }
};





David Brown

unread,
Oct 6, 2022, 8:16:49 AM10/6/22
to
You should prefer the sized types here - int64_t or uint64_t. People
can - and have - argue endlessly about the pros and cons of different
types. But when you know you need a precise size, and anything else
would be wrong, then it is best to specify that.


Scott Lurndal

unread,
Oct 6, 2022, 10:03:30 AM10/6/22
to
In theory, but not necessarily in practice. It works just fine with g++.

Lynn McGuire

unread,
Oct 6, 2022, 4:08:17 PM10/6/22
to
Yeah, I have been thinking about changing f2c to use that. Since it
uses its own definitions in f2c.h, anything can be easily changed. f2c
is a fairly old software so it has dated types in it.

typedef long int integer;
typedef unsigned long int uinteger;
typedef char *address;
typedef short int shortint;
typedef float real;
typedef double doublereal;
typedef struct { real r, i; } complex;
typedef struct { doublereal r, i; } doublecomplex;
typedef long int logical;
typedef short int shortlogical;
typedef char logical1;
typedef char integer1;
typedef long long longint; /* system-dependent */
typedef long long logical8; /* system-dependent */
typedef unsigned long long ulongint; /* system-dependent */
#define fstring fem::str

Lynn


David Brown

unread,
Oct 7, 2022, 3:08:12 AM10/7/22
to
An alternative if you want to keep C90 support (well, C90 with "long
long" support) would be to include <limits.h> and add some compile-time
checks on the sizes. The point is to be sure that the sizes are what
you expect them to be.

You will also want to change the "logical1" and "integer1" typedefs. It
is madness to use a plain "char" for anything other than an ASCII
character. You want "signed char" for "integer1", and I would have
thought "unsigned char" is the appropriate choice for "logical1".


Lynn McGuire

unread,
Oct 7, 2022, 3:23:33 PM10/7/22
to
I don't use those types in my code so I don't care. Those types are
just in the standard f2c.h declaration.

Thanks,
Lynn

Bonita Montero

unread,
Oct 10, 2022, 12:04:26 PM10/10/22
to
Am 05.10.2022 um 03:41 schrieb Lynn McGuire:

> How do I specify an 8 byte bool ?  Long long ?

If you use a long long you most times need a size_t on 64 bit platforms
and a 32 bit size_t on 32 bit platforms. size_t'd bools might make sense
to address two entities following each other in an array depending on
the result of a boolean operation. Even this silly RISC-V-platform has
an operation to load a zero or a one into a register depending on the
result of a comparison (unfortunately that's the only predicated opera-
tion that RISC-V has).

0 new messages