[C99] how to test if type uint32_t exists?

F

Francois Grieu

Hi, a basic question. After
#include <stdint.h>

it seems the standard allows uint32_t notto be defined, e.g. on a
36-bit machine.

How can we make a preprocessor test on if uint32_t is defined or not?
That would come handy to portably decide between using uint32_t,
or reverting to some alternate strategy using explicit masking.

TIA

Francois Grieu
 
B

Ben Pfaff

Francois Grieu said:
Hi, a basic question. After
#include <stdint.h>

it seems the standard allows uint32_t notto be defined, e.g. on a
36-bit machine.

How can we make a preprocessor test on if uint32_t is defined or not?

I think that
#ifdef UINT32_MAX
ought to work.
 
F

Francois Grieu

I asked
Hi, a basic question. After
#include <stdint.h>

it seems the standard allows uint32_t not to be defined, e.g. on a
36-bit machine.

How can we make a preprocessor test on if uint32_t is defined or not?
That would come handy to portably decide between using uint32_t,
or reverting to some alternate strategy using explicit masking.


Thinking about it, could this NOT do the trick?
#include <stdint.h>
#ifdef UINT32_MAX

Francois Grieu
 
E

Ersek, Laszlo

Hi, a basic question. After
#include <stdint.h>

it seems the standard allows uint32_t notto be defined, e.g. on a
36-bit machine.

How can we make a preprocessor test on if uint32_t is defined or not?
That would come handy to portably decide between using uint32_t,
or reverting to some alternate strategy using explicit masking.

#include <inttypes.h>

#ifdef PRIu32
....
#endif

C99 7.8.1 "Macros for format specifiers", p6:

"For each type that the implementation provides in <stdint.h>, the
corresponding fprintf macros shall be defined [...]"

Strictly speaking, this is only one direction (implication), not
equivalence. Ie. IF uint32_t is provided, THEN PRIu32 is #defined.
Nothing is said about PRIu32 if uint32_t is not provided, but I believe
it would be very strange for an implementation to #define an fprintf
conversion specifier for a type it doesn't support. I also think that
this reverse direction is implied in the standard's text.

lacos
monkey
 
I

ImpalerCore

Hi, a basic question. After
#include <stdint.h>

it seems the standard allows uint32_t notto be defined, e.g. on a
36-bit machine.

How can we make a preprocessor test on if uint32_t is defined or not?
That would come handy to portably decide between using uint32_t,
or reverting to some alternate strategy using explicit masking.

The two most popular choices come down to creating an arbitrary tree
of #ifdef statements to check for specific platform/compiler/version
combinations (this requires specific knowledge whether each of the
target environments you use support stdint.h, and if it does, that it
supports uint32_t), or you use an autoconf like test that compiles a
simple test program and generates a config.h that defines something
like HAVE_STDINT_H or HAVE_UINT32_T.

There's also the manual approach where you provide a config.h and the
user is responsible for editing its contents. It's not typically
preferred, but it's an option.

---config.h---
/* Uncomment if you have stdint.h header support. */
#if !defined(HAVE_STDINT_H)
/* # define HAVE_STDINT_H */
#endif
---

---intwrapper.h---
#if defined(HAVE_STDINT_H)
# include <stdint.h>
#else
typedef unsigned long uint32_t;
#endif
 
I

ImpalerCore

The two most popular choices come down to creating an arbitrary tree
of #ifdef statements to check for specific platform/compiler/version
combinations (this requires specific knowledge whether each of the
target environments you use support stdint.h, and if it does, that it
supports uint32_t), or you use an autoconf like test that compiles a
simple test program and generates a config.h that defines something
like HAVE_STDINT_H or HAVE_UINT32_T.

There's also the manual approach where you provide a config.h and the
user is responsible for editing its contents.  It's not typically
preferred, but it's an option.

---config.h---
/* Uncomment if you have stdint.h header support. */
#if !defined(HAVE_STDINT_H)
/* #  define HAVE_STDINT_H */
#endif
---

---intwrapper.h---
#if defined(HAVE_STDINT_H)
#  include <stdint.h>
#else
typedef unsigned long uint32_t;
#endif
---

Hope it helps.


- Show quoted text -
 
I

ImpalerCore

Hi, a basic question. After
#include <stdint.h>
it seems the standard allows uint32_t notto be defined, e.g. on a
36-bit machine.
How can we make a preprocessor test on if uint32_t is defined or not?
That would come handy to portably decide between using uint32_t,
or reverting to some alternate strategy using explicit masking.

#include <inttypes.h>

#ifdef PRIu32
...
#endif

C99 7.8.1 "Macros for format specifiers", p6:

"For each type that the implementation provides in <stdint.h>, the
corresponding fprintf macros shall be defined [...]"

Strictly speaking, this is only one direction (implication), not
equivalence. Ie. IF uint32_t is provided, THEN PRIu32 is #defined.
Nothing is said about PRIu32 if uint32_t is not provided, but I believe
it would be very strange for an implementation to #define an fprintf
conversion specifier for a type it doesn't support. I also think that
this reverse direction is implied in the standard's text.

In my case, the PRIu32 isn't defined in its stdint.h, but UINT32_MAX
is. Granted it's an older embedded C compiler for a PIC, but
unfortunately not all compilers have a standard compliant
implementation.

Best regards,
John D.
 
E

Ersek, Laszlo

On Feb 19, 3:38=A0pm, (e-mail address removed) (Ersek, Laszlo) wrote:

In my case, the PRIu32 isn't defined in its stdint.h, but UINT32_MAX
is. Granted it's an older embedded C compiler for a PIC, but
unfortunately not all compilers have a standard compliant
implementation.

If PRIu32 is defined, it is defined in <inttypes.h>, not <stdint.h>.
Nonetheless, UINT32_MAX is probably a much better choice, I missed it,
sorry.

Cheers,
lacos
 
I

ImpalerCore

If PRIu32 is defined, it is defined in <inttypes.h>, not <stdint.h>.
Nonetheless, UINT32_MAX is probably a much better choice, I missed it,
sorry.

No need to apologize, I appreciate your comments. And yes, the PIC
compiler does not have an inttypes.h.
 
F

Francois Grieu

christian.bau a écrit :
Question: So what are you going to do if uint32_t is not available?

Use another type at least 32-bit, and mask explicitly when needed.
You'll have to write code that either uses unsigned long, or that uses
unsigned long or unsigned int, depending on the size of unsigned int.
And you can't rely on properties of uint32_t, like the property that
(x >> 31) is either 0 or 1 and nothing else. You could have written
code that way in the first place instead of using uint32_t.

I keep the maximum value TU32MAX of whatever type tu32 I select, and
construct a macro
#if TU32MAX==0xFFFFFFFF
#define TU32LOW(x) (tu32)(x)
#else
#define TU32LOW(x) (tu32)((tu32)(x)&(tu32)0xFFFFFFFF)
#endif

I then use it, depending on context
- whenever a result can overflow 32 bit (e.g. after additon,
multiplication, left shift.. but not right-shift, xor..)
- whenever an input can overflow 32-bit and matter (e.g. before
right shift)
You have basically two choices: You use uint32_t and declare that your
code will just not compile on an implementation where it isn't
defined. No need to check; the compiler will tell you. Or you require
your code to run without uint32_t present - then just don't use it.

I prefer the first option you describe, or the alternative I describe.
I want to use uint32_t if it exists and the straight TU32LOW, else
some other type and the masking TU32LOW; I hope uint32_t might be faster.


Francois Grieu
 

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,995
Messages
2,570,233
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top