1

My understanding per reading C99 [PDF] is that it declares types (e.g. unsigned int) in terms of rank, range, etc. in such a way that does not mandate a maximum true bit size, although a minimum size is implied. I've read on StackOverflow that while unsigned int compiles as uint32_t on 32-bit platforms, it may be promoted to 64-bit on X86-64 platforms. Further, Wikipedia says the Unix/Linux family of operating systems uses 64-bit for long by default. Posts indicate that the main concern is unexpected behavior; performance issues of promoting or not promoting appear to be secondary.

To avoid potential unexpected behavior, when porting a program from one platform to another (e.g. porting a Windows app to Linux), is it possible to force the compiler (e.g. gcc) to not only abide by a certain maximum bit width for a specific type (e.g. enforce long to be guaranteed as 32-bit in the context of the current code, contrary general platform sizing), but to ALSO enforce such a restriction on all math ops / intermediate results in math ops involving that restricted value?

There's been discussion of how to restrict long to a specific size by value, but that appears limited to restricting the values themselves, not ops.

If promotion can still occur -- per the post regarding int32_t multiplication and unexpected overflows during automatic promotion in code compiled on X86-64 CPUs -- restricting by value doesn't ensure expected results / consistency.

How can we restrict not only the values, but intermediates from ops, as well?

Does the ability to enforce a maximum bit width in all operations relative a specific type (assuming that's possible) vary by compiler or is it standardized in some way?

i.e. if long is natively 64-bit, can we force it to be 32-bit via certain preprocessor directives, etc.?

Jason R. Mick
  • 5,177
  • 4
  • 40
  • 69
  • "enforce long to be guaranteed as 32-bit?". By using `int32_t` instead of `long`. – Weather Vane Aug 22 '17 at 20:54
  • `uint32_t t;` - `t` is guaranteed to be 32 bit @Groo – 0___________ Aug 22 '17 at 20:57
  • 1
    @PeterJ: well, that's what OP said too, I misread the question the first time, I thought it said `uint32_t` is 64-bit. Never mind. Of course the promotion happens in expressions according to promotion rules, it doesn't "become" 64-bit, that's what I wanted to say. – vgru Aug 22 '17 at 21:01
  • 1
    Possible duplicate of [Making 'long' 4 bytes in gcc on a 64-bit Linux machine](https://stackoverflow.com/questions/12794603/making-long-4-bytes-in-gcc-on-a-64-bit-linux-machine) – vgru Aug 22 '17 at 21:03
  • `uint32_t` isn't guaranteed to stay 32-bit if it say undergoes a math op, correct? The linked question suggests that... let me update the wording of my question mildly to clarify the intent. – Jason R. Mick Aug 22 '17 at 21:03
  • 1
    @JasonR.Mick: yes, the linked question decribes a valid UB case. – vgru Aug 22 '17 at 21:04
  • You may be able to use `gcc -m32` to do a 32-bit compilation where the type of `long` will also be 32 bits. However, even on iOS, 32-bit applications are going the way of the dodo. You need to design the software so that it works correctly provided the architecture provides the minimum levels of support you need. Note that compiling for 32-bit requires a 32-bit O/S API; that which works OK with 64-bit may not work at all, or may work incorrectly, with 32-bit. It is a non-trivial exercise. – Jonathan Leffler Aug 22 '17 at 21:06
  • @Jason R. Mick it is, – 0___________ Aug 22 '17 at 21:08
  • Does `-m32` support ops as well? Sorry, guys that was the crux of my question (to address your comment esp. @Groo)... I should have been clearer... I'm interested in whether end-to-end sort of enforcement is possible, i.e. if any intermediates (per the math op post linked) get promoted, then I'd consider that a violation of the spirit of my question. I've read several posts on values, but I see people posting apparent work arounds to enforce op bit restrictions. – Jason R. Mick Aug 22 '17 at 21:13
  • 1
    Some platforms have even special instructions for it https://godbolt.org/g/bcLZPW – 0___________ Aug 22 '17 at 21:13
  • gcc has those types built in for example `__UINT32_TYPE__` – 0___________ Aug 22 '17 at 21:18
  • Just to clarify... I have `uint32_t s1` and `uint32_t s2`, and I want to ensure `*` does not promote during `s1 * s2`. It sounds like the types are not sufficient to enforce that. Does compiling with `-m32` and 32-bit libraries on a 64-bit platform prevent not only value promotion, but promotion during the `*` op as well? – Jason R. Mick Aug 22 '17 at 21:24

1 Answers1

1

You have special types in the stdint.h

uint8_t, uint16_t, uint32_t & uint64_t - for unsigned
int8_t, int16_t, int32_t & int64_t - for signed

Those types guarantee the width of the object;

0___________
  • 60,014
  • 4
  • 34
  • 74