int*_t, int_least*_t, int_fast*_t signedness

  • Thread starter Philipp Klaus Krause
  • Start date
P

Philipp Klaus Krause

I have seen these typically typedefed to a type that does not have the
"signed" keyword, e.g. in my linux stdint.h (it's the same in e.g. sdcc):

typedef int int_fast16_t;

is this a correct way to create the int_fast16_t type? I would have
expected it to be e.g.:

typedef signed int int_fast16_t;

and was quite surprised when I found my int_fast16_t bitfield to be
unsigned.

Philipp
 
B

Ben Bacarisse

Philipp Klaus Krause said:
I have seen these typically typedefed to a type that does not have the
"signed" keyword, e.g. in my linux stdint.h (it's the same in e.g. sdcc):

typedef int int_fast16_t;

is this a correct way to create the int_fast16_t type?

Looks fine to me.
I would have
expected it to be e.g.:

typedef signed int int_fast16_t;

That means the same: int is signed int. Unsigned types need the
'unsigned' keyword but signed types do not need 'signed'. There are two
exceptions: plain 'char' and bit-fields declared with plain 'int'. It
is up to the implementation to decide if these are signed or unsigned.
and was quite surprised when I found my int_fast16_t bitfield to be
unsigned.

You found one of the exceptions! You can decide on the signedness of a
bit field by being explicit about it. BTW int must have at least 16
bits so there is no point in using int_fast16_t rather than int. If a
wider int is required to be "fast" on some machine, you will loose the
benefit by making it a bitfield. I.e. just use 'signed int'.

[This does exclude some possible peculiar corner cases on, say, sign and
magnitude machines.]
 
E

Eric Sosman

I have seen these typically typedefed to a type that does not have the
"signed" keyword, e.g. in my linux stdint.h (it's the same in e.g. sdcc):

typedef int int_fast16_t;

is this a correct way to create the int_fast16_t type? I would have
expected it to be e.g.:

typedef signed int int_fast16_t;

and was quite surprised when I found my int_fast16_t bitfield to be
unsigned.

Adding to Ben Bacarisse's response, note that the only
universally portable bit-field "base types" are signed int,
unsigned int, and (in C99) _Bool. Any other types are usable
at the implementation's discretion; some may accept them and
some may not. If an implementation accepts additional types,
the semantics are the implementation's business.

In short, the signedness of a bit-field with the base type
int_fast16_t is not specified by the Standard, so your compiler
has not broken the rules of C by making it unsigned.
 
K

Keith Thompson

Eric Sosman said:
Adding to Ben Bacarisse's response, note that the only
universally portable bit-field "base types" are signed int,
unsigned int, and (in C99) _Bool. Any other types are usable
at the implementation's discretion; some may accept them and
some may not. If an implementation accepts additional types,
the semantics are the implementation's business.

int is also universally portable, but it's implementation-defined
whether it's signed or unsigned. Because of this, it rarely makes
sense to have a bit-field of type signed int.
In short, the signedness of a bit-field with the base type
int_fast16_t is not specified by the Standard, so your compiler
has not broken the rules of C by making it unsigned.

To clarify, not only the signedness, but the legality, of
an int_fast16_t bit field is not specified by the Standard.
If int_fast16_t happens to be a typedef for int, then an int_fast16_t
bit field is legal and of impementation-defined signedness. If not,
an int_fast16_t bit field is legal only if the implementation
supports it as an extension.
 
E

Eric Sosman

int is also universally portable, but it's implementation-defined
whether it's signed or unsigned.

That's why I left it out of the "universally portable" list,
but perhaps I should have been clearer: Yes, plain int is accepted
by all conforming implementations, but the semantics are not
portable since they vary from implementation to implementation.
Because of this, it rarely makes
sense to have a bit-field of type signed int.

Did you mean to say "plain int" here? If not, could you
explain why it rarely makes sense to have a bit-field with an
assuredly negative value?
 
K

Keith Thompson

Eric Sosman said:
On 6/14/2010 11:16 AM, Keith Thompson wrote: [...]
Because of this, it rarely makes
sense to have a bit-field of type signed int.

Did you mean to say "plain int" here? If not, could you
explain why it rarely makes sense to have a bit-field with an
assuredly negative value?

Yes, I meant to say "plain int". Sorry.

(Signed bit fields are rarer than unsigned bit fields, but they can
certainly make sense.)

As for using plain int, I can imagine cases where you want a bit field
to occupy N bits, but you're only going to store values in the range
0..2**(N-1)-1, so you don't care whether it's signed or unsigned.
In that case, letting the implementation choose whichever is more
efficient makes some sense.

Or you might be willing to depend on the implementation-defined
signedness of a plain int bit-field, but then you might as well use
"signed int" or "unsigned int" explicitly.
 

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,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top