Size of bool unspecified: why?

I

Ian Collins

Why is "unspecified" necessary? Does anyone think that not specifying the
size of a bool is a good thing?

How can bools be used in structs if every implementation can define it
differently?

The same way ints can be used in structs when every implementation can
define them differently.
Oh yeah! The 2 groups should have coordinated the introduction of bool.

C++ had bool 10 years before it found its way into C.
I meant efficient in time, not space. Are not 64-bit ints indeed more
efficient (in time) than 32-bit ints, say on x86 vs. x64? Anyone have a
good simple test for this? Probably at least 3 things need to be eval'd:
argument passing performance, return value performance, arithmetic
performance. I can compare the 8-bit bool vs. a 32-bit int on my machine,
but I don't have a 64-bit machine.

Efficient in time can be the same as efficient in space. The most
valuable resource on modern CPUs is the cache, the bigger a data type,
the quicker the cache overflows. That's why performance of some
applications is better built 64 bit and worse for others.
 
J

JBarleycorn

Ian Collins said:
The same way ints can be used in structs when every implementation can
define them differently.

You can used fixed-width integers but there is no complementary bool
type. bool is unusable in structs in many instances then. Serialization
is not a panacea, it's tedium.
C++ had bool 10 years before it found its way into C.

Like I said, they should have coordinated the introduction of bool.
Efficient in time can be the same as efficient in space. The most
valuable resource on modern CPUs is the cache, the bigger a data type,
the quicker the cache overflows. That's why performance of some
applications is better built 64 bit and worse for others.

I guess I'll just have to profile it myself and see if there is
significant difference.
 
I

Ian Collins

You can used fixed-width integers but there is no complementary bool
type. bool is unusable in structs in many instances then. Serialization
is not a panacea, it's tedium.

The only places where sizeof(bool) matters it will be defined.
I guess I'll just have to profile it myself and see if there is
significant difference.

Define "it".

What part of "performance of some applications is better built 64 bit
and worse for others" didn't you get?
 
J

JBarleycorn

Ian Collins said:
The only places where sizeof(bool) matters it will be defined.

The need for fixed-width integers has been proven and therefore they are
in the standard, but then they forget the past and create a new type and
don't consider that width matters for that type. Either that or they
considered it not useful in the situations where the fixed-width integers
are a boon. They should have specified a width, as the alternative of
having multiple booleans of different widths isn't practical I believe.

A header of an application program can check if fixed-width integer types
are what the program expects and if not, then adjustments can be made,
but with bool, whaddaya going to do if the size of bool doesn't meet the
app's expectations? Use an integer of the right size? What's the point of
having a bool at all then if it is likely that some compiler or version
of it doesn't support the needed type?

It seems that any case you make for the width of bool being OK
unspecified, refutes the need for fixed-width integer types, and
vice-versa. Where is the consistency?
Define "it".

What part of "performance of some applications is better built 64 bit
and worse for others" didn't you get?

I don't think it is as nebulous as you make it seem. I gave 3 instances:
arguments, return vals and arithmetic. I don't believe that *no*
conclusions can be drawn from analysis of those instances in regards to
integer sizes. Yes, the assumptions (platforms, compilers...) will have
to be stated, but that's how scientific study works: you study some
finite subset of the universe to gain insight. That insight, as a
practical matter, is what I was looking for. If I was building a language
from scratch and choosing a size for the boolean type, the performance of
that type, as a practical matter, would or might factor into the design
of that type. Similarly, if I was introducing a boolean type into a
language that does not yet have one, I would consider the same issue.
 
I

Ian Collins

The need for fixed-width integers has been proven and therefore they are
in the standard, but then they forget the past and create a new type and
don't consider that width matters for that type. Either that or they
considered it not useful in the situations where the fixed-width integers
are a boon. They should have specified a width, as the alternative of
having multiple booleans of different widths isn't practical I believe.

That argument doesn't make sense, given we have fixed with types, why
should the with of any natural type be fixed? The analogy with int
still applies. If I want a 32 bit signed type, I'll use int32_t.
Whether that is an int or a long under the hood is irrelevant.
A header of an application program can check if fixed-width integer types
are what the program expects and if not, then adjustments can be made,
but with bool, whaddaya going to do if the size of bool doesn't meet the
app's expectations?

Who often have you needed to know the size of bool? What do you do if
sizeof(int) isn't what the program expects? You use a different type.
How is bool different?
Use an integer of the right size? What's the point of
having a bool at all then if it is likely that some compiler or version
of it doesn't support the needed type?

Again, how often is the size of a natural type important? How often in
real code do you use a fixed width type? I'm sure I use them more than
most because a lot of my work is on embedded platforms or drivers. I
seldom use them anywhere else.
It seems that any case you make for the width of bool being OK
unspecified, refutes the need for fixed-width integer types, and
vice-versa. Where is the consistency?

It isn't unspecified, it is implementation defined, just like int.
I don't think it is as nebulous as you make it seem. I gave 3 instances:
arguments, return vals and arithmetic. I don't believe that *no*
conclusions can be drawn from analysis of those instances in regards to
integer sizes. Yes, the assumptions (platforms, compilers...) will have
to be stated, but that's how scientific study works: you study some
finite subset of the universe to gain insight.

Thing go horribly wrong when you study the wrong subset.
That insight, as a
practical matter, is what I was looking for. If I was building a language
from scratch and choosing a size for the boolean type, the performance of
that type, as a practical matter, would or might factor into the design
of that type. Similarly, if I was introducing a boolean type into a
language that does not yet have one, I would consider the same issue.

So what would you do if 8 bits performed best on one platform and 32 on
another? You would make the size implementation defined.
 
J

James Kanze

Isn't that the same thing?

No. Unspecified means that you cannot know or depend on the
size; it might change from one compilation to the next.
Implementation defined means that each implementation must
define it, and document how it is defined.
C compatibility where layout, then, matters? Data transfer/storage.

C didn't have bool, so there can't be an issue of C
compatibility. As for data transfer and storage, you treat it
like any other type: you define the external format, and
implement the conversion. In practice, it's probably simpler to
handle than most other types, since it's relatively trivial to
handle all possible values separately.
Efficiency?

That's why I said: on a byte addressable machine.
See, efficiency.

That's one of the arguments for making it the same size as a
word. On a machine which isn't byte addressable. (Such
machines are fairly rare today.)
Right, but a type that need not be promoted does not need that extra
step.

If the representation is a single byte, and the both the caller
and the callee agree, there's no need for extension. Extension
is only necessary if you have a smaller size, and need to pass a
larger one.

Depending on the architecture, it may be necessary, or more
efficient, to pass par a register, rather than to push directly
onto the stack, if the bool is in an array (and thus
misaligned).
But compilers probably don't do that.

Have you actually verified that? I would expect almost every
compiler to do so when it is advantageous.
What is common practice though is the real concern because just about
everything in C++ is platform-dependent.

Even common practice depends on the platform. Common practice
on an Intel will be different than common practice on a Sparc.
For that matter, common practice under Windows is different than
common practice under Linux, even when both run on a 32 bit
Intel.
 
J

James Kanze

Why is "unspecified" necessary? Does anyone think that not specifying the
size of a bool is a good thing?

First, I don't think it's unspecified. Implementation defined,
on the other hand, is necessary in order for C++ to be
implementable on all platforms. (Reasonably, at least.)
How can bools be used in structs if every implementation can define it
differently?

How can ints be used in structs if every implementation can
define them differently. On a given platform, if there is a C++
API, all reasonable implementations will adhere to it. If there
isn't, then you can't link code compiled with different
compilers. Bool or no.
Oh yeah! The 2 groups should have coordinated the introduction of bool.

But they didn't. C wasn't interested (at the time).

[...]
I meant efficient in time, not space.

The two are related. Locality is an important issue on today's
machines.
Are not 64-bit ints indeed more
efficient (in time) than 32-bit ints, say on x86 vs. x64? Anyone have a
good simple test for this?

It depends on how you use them, but I'd be very surprised if
there were any use cases where 64 bit ints would be faster than
32 bit ints.
Probably at least 3 things need to be eval'd:
argument passing performance, return value performance, arithmetic
performance.

Plus about a dozen other parameters. In practice, the limiting
factor for performance on today's machine is how many values fit
in a cache line.
 
P

Pawel Dziepak

Juha said:
Probably for the same reason that the size of *any* basic type (with
the exception of char) is unspecified?

In fact, the size of char is also implementation defined. sizeof(char) ==
1, but there is no guarantee that it means that char is 8 bit wide. What
the standard tells about char is that it is large enough to store
"implementation's basic character set". There is nothing that forbids,
e.g., 9-bit chars.
 
J

James Kanze

In fact, the size of char is also implementation defined. sizeof(char) ==
1, but there is no guarantee that it means that char is 8 bit wide. What
the standard tells about char is that it is large enough to store
"implementation's basic character set". There is nothing that forbids,
e.g., 9-bit chars.

There is, in fact, at least one modern implementation which uses
9 bit chars. There are also, from what I've been told, a couple
which use 32 bit chars.
 
J

James Kanze

You can used fixed-width integers but there is no complementary bool
type.

The only fixed-width types I know are optional, and aren't
supported by implementations which don't have immediate hardware
support for them. Their use is fairly limited, and I can't
think of a case where I'd use them in a struct. (They are
convenient for certain operations, however, when their
restricted portability isn't an issue.)
bool is unusable in structs in many instances then.

You keep saying this, but it flies in the face of actual facts.
People use bool in structs all the time, with no problems.
Serialization is not a panacea, it's tedium.

You've mentionned serialization several times, but you've yet to
explain how the fact that the size of bool being implementation
defined affects it in any way. The internal representation
doesn't generally affect serialization. And it varies, not just
for bool, but for int.
 
J

James Kanze

Isn't that the same thing?
[/QUOTE]
Implementation defined has to be documented, unspecified does
not. Both are behaviors defined by the implementation.

Unspecified means not undefined in the sense of the standard,
but not only does it not have to be documented, it may vary. At
least in principle, if bool is unspecified, it could be 32 bits
one time you ran the program, 8 another time. Or 32 bits in one
part of the program, and 8 elsewhere. (I can't imagine how this
could be the case practically. But then, I think the size of
bool is implementation defined, and not unspecified.
Unspecified is generally reserved for things where different
optimizations could result in different behavior, e.g. whether
the results of a floating point operation are in extended
precision, or strictly double.)
 
N

Nick Keighley

Why is "unspecified" necessary? Does anyone think that not specifying the
size of a bool is a good thing?

me! Didn't a previous poster give you good reasons?

How can bools be used in structs if every implementation can define it
differently?

in what way does bool differ from the other C++ (and C) types. All of
them have implementation defined sizes!


anyone using structs for data transfer is in a state of sin.


<snip>
 
J

JBarleycorn

Ian said:
That argument doesn't make sense, given we have fixed with types, why
should the with of any natural type be fixed? The analogy with int
still applies. If I want a 32 bit signed type, I'll use int32_t.
Whether that is an int or a long under the hood is irrelevant.


Who often have you needed to know the size of bool? What do you do if
sizeof(int) isn't what the program expects?

Why would anyone expect sizeof(int) to be anything specific? int is not
an issue. The fixed-width sizes are an issue, but you can test for it and
do whatever is necessary to maintain consistency.
You use a different type.

A different numeric type, which there are a number to choose from. Who
writes a program that doesn't have a header that tests for assumptions
based upon the platform?
How is bool different?

If bool doesn't meet your expectations, you don't have the option to
change to a similar type of different width, because there is no similar
type of different width. You have to change compilers or something. *Or*,
avoid bool from the get go noting from the start that you can't rely on
the width of bool. What the current practice is across a wide variety of
compilers, or just the "major" ones, I don't know: that would be good
info and maybe some consolation, but bool does appear to be broken from
the get go.
Again, how often is the size of a natural type important?

*Very* often.
How often
in real code do you use a fixed width type?

*Very* often. *Very* much more often than using non-fixed-width integral
types.
I'm sure I use them more
than most because a lot of my work is on embedded platforms or
drivers.

Well there you go then.
I seldom use them anywhere else.


It isn't unspecified, it is implementation defined, just like int.

The same issue exists with int, *but* there are the alternative
fixed-width integral types and even when their weren't the fixed-width
types, there was still enough choice there to get what is desired. I use
a boolean class, where I can control the width and still get the behavior
of a boolean, for use in structs but I have to because built-in bool is
broken.
Thing go horribly wrong when you study the wrong subset.


So what would you do if 8 bits performed best on one platform and 32
on another?

I would use that information in choosing a design.
You would make the size implementation defined.

No, not likely for then bool would be eliminated from a lot of places
where it could be used to good effect. I think multiple-width boolean
types can be made to work, but the complexity is not worth it, so 1-byte
bools, even though there may be a performance penalty on most platforms,
are probably the best choice. I have pretty much decided that where a
"fast bool" is needed it's a profile/optimizaation thing and trying to
find an optimum boolean type size as the best compromise across a set of
platforms falls into the category of premature optimization. Therefore,
the overriding concern is suitability for use as a struct field. So, my
boolean class uses a 1-byte type as the underlying type.
 
I

Ian Collins

Why would anyone expect sizeof(int) to be anything specific? int is not
an issue. The fixed-width sizes are an issue, but you can test for it and
do whatever is necessary to maintain consistency.


A different numeric type, which there are a number to choose from. Who
writes a program that doesn't have a header that tests for assumptions
based upon the platform?

Anyone who is writing for a specific platform, or who doesn't care about
the sizes of natural types.
If bool doesn't meet your expectations, you don't have the option to
change to a similar type of different width, because there is no similar
type of different width. You have to change compilers or something. *Or*,
avoid bool from the get go noting from the start that you can't rely on
the width of bool. What the current practice is across a wide variety of
compilers, or just the "major" ones, I don't know: that would be good
info and maybe some consolation, but bool does appear to be broken from
the get go.

OK, give one concrete example where the size of bool matters.
*Very* often.

So you are writing embedded code or drivers? There are very few other
places where the size of type matters.
The same issue exists with int, *but* there are the alternative
fixed-width integral types and even when their weren't the fixed-width
types, there was still enough choice there to get what is desired. I use
a boolean class, where I can control the width and still get the behavior
of a boolean, for use in structs but I have to because built-in bool is
broken.

You keep staying bool is broken, but you still haven't provided any real
world examples to back it up.
I would use that information in choosing a design.

How would your design cope with both 8 bit MCUs and 32 bit DSPs (where
CHAR_BIT = 32)?
No, not likely for then bool would be eliminated from a lot of places
where it could be used to good effect.

Please name one.
 
J

JBarleycorn

James said:
The only fixed-width types I know are optional, and aren't
supported by implementations which don't have immediate hardware
support for them.

That's OK. I've been using fixed-width integral types long before there
were such syntactic sugaring things like those defined in stdint.h.
Their use is fairly limited, and I can't
think of a case where I'd use them in a struct. (They are
convenient for certain operations, however, when their
restricted portability isn't an issue.)

You view of the concept seems to be exactly the opposite of mine. Your
view seems more appropriate, to me, for a 4GL rather than for C/C++.
You keep saying this, but it flies in the face of actual facts.

It depends on how you program. When I say that, I mean for the way I
program and use the language.
People use bool in structs all the time, with no problems.

If I had to be continually faced with having to think about what the
effect of integral type size changes would be in C++, I would not use the
language. Though maybe I wouldn't program at all then!
You've mentionned serialization several times, but you've yet to
explain how the fact that the size of bool being implementation
defined affects it in any way. The internal representation
doesn't generally affect serialization. And it varies, not just
for bool, but for int.

int and bool are in the same boat in that respect. The *only* time I use
int, or its unsigned counterpart, is when I consciously *want* a type to
expand across 32-bit and 64-bit platforms, and yes, I test in a header if
my assumptions are valid on a given platform. I view fixed-width integral
types, even if I have to synthesize them as I did before there was
stdint.h, as the "normal" ones and the "expanding" types as the special
ones. Try it sometime and you'll probably never go back to the other way
of thinking.
 
J

JBarleycorn

James said:
First, I don't think it's unspecified.

This "unspecified" designation is something new to me. I don't really
understand the point of it or how to determine if something is
"implementation defined" or that.
Implementation defined,
on the other hand, is necessary in order for C++ to be
implementable on all platforms. (Reasonably, at least.)


How can ints be used in structs if every implementation can
define them differently.

There are a few different integral types, that are not boolean, from
which to synthesize "fixed-width" integral types.
On a given platform, if there is a C++
API, all reasonable implementations will adhere to it. If there
isn't, then you can't link code compiled with different
compilers. Bool or no.

APIs are only half of the story.
But they didn't. C wasn't interested (at the time).

Right, they didn't, but had they, they would have stood at least some
chance at not implementing a boolean type that is broken.
[...]
I meant efficient in time, not space.

The two are related. Locality is an important issue on today's
machines.

No need to be pedantic.
It depends on how you use them, but I'd be very surprised if
there were any use cases where 64 bit ints would be faster than
32 bit ints.

I was thinking that the register size and instructions on a 64-bit
machine would somehow favor 64-bit operations.
Plus about a dozen other parameters.

In usage, those probably cover enough of the territory. From a language
implementation standpoint, some of those 12 others you have in mind may
be important. What are the 12 others you have in mind?
In practice, the limiting
factor for performance on today's machine is how many values fit
in a cache line.

Do you know of any test suites to analyze such? That is, not the cache
line thing, but the integral type thing, for the latter is the more
abstract thing.
 
J

JBarleycorn

Nick said:
me! Didn't a previous poster give you good reasons?

Apparently not.
in what way does bool differ from the other C++ (and C) types. All of
them have implementation defined sizes!

See my response to JKazne for it should answer your question.
anyone using structs for data transfer is in a state of sin.

Try it sometime. Your paradigm may be holding back your potential.
 
J

JBarleycorn

James said:
There is, in fact, at least one modern implementation which uses
9 bit chars. There are also, from what I've been told, a couple
which use 32 bit chars.

Anything that implements char as anything other than 8-bits is an exotic,
IMO, and therefore does not deserve to taint all other code for its
existence. Special circumstances require special handling. Code for the
common case, to some defined "common", and not for the exceptional case.
Imagine telling your client that you didn't take advantage of the fact
that most platforms define char as 8-bits and then telling them the
statistics and applicability to their needs of those exotic platforms.
They would run you out of town on a rail.. or *should*!
 
J

JBarleycorn

James said:
Unspecified means not undefined in the sense of the standard,
but not only does it not have to be documented, it may vary. At
least in principle, if bool is unspecified, it could be 32 bits
one time you ran the program, 8 another time. Or 32 bits in one
part of the program, and 8 elsewhere. (I can't imagine how this
could be the case practically. But then, I think the size of
bool is implementation defined, and not unspecified.
Unspecified is generally reserved for things where different
optimizations could result in different behavior, e.g. whether
the results of a floating point operation are in extended
precision, or strictly double.)

Can anyone here say definitively whether bool is this "unspecified" thing
or ""implemetation defined" or... ? (!)
 
I

Ian Collins

Can anyone here say definitively whether bool is this "unspecified" thing
or ""implemetation defined" or... ? (!)

From

5.3.3 1

"[Note: in particular, sizeof(bool) and sizeof(wchar_t) are
implementation-defined]"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,996
Messages
2,570,237
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top