Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it sane to include casts in #defined constants based on how they're intended to be used?

Tags:

c

Say I have a bunch of un-magicked constants that have been given symbolic names in the header file of a gyroscope module gyro.h:

#define GYRO_SPI_TIMEOUT 1000

In this instance, the hardware abstraction libraries for my MCU use uint32_t for the number of milliseconds. Is it sensible to, in lieu of allocating space and defining these as const, add type information in the macro?

#define GYRO_SPI_TIMEOUT ((uint32_t) 1000)

What are the benefits and drawbacks of this approach?

like image 701
josaphatv Avatar asked Feb 01 '15 17:02

josaphatv


People also ask

What does it mean to have casts in urine?

Fatty casts are seen in people who have lipids in urine. This is most often a complication of nephrotic syndrome . Granular casts are a sign of many types of kidney diseases. Red blood cell casts mean there is a microscopic amount of bleeding from the kidney. They are seen in many kidney diseases.

Should there be casts in urine?

If a cast is seen in the urine, kidney disease or in- volvement exists; the presence of casts indicates kidney (renal) disease rather than lower urinary tract disease. All casts have a matrix of Tamm- Horsfall mucoprotein to which other pro- teins or elements may be added.

What is the normal range for casts in urine?

Normally, very few casts are seen in urine examinations without renal dysfunction. Hyaline casts are the most frequently observed, and zero to two casts per low-power field is considered normal.

How do you report casts in urine?

Casts are quantified for reporting as the number seen per low power field (10x objective) and classified as to type (e.g., waxy casts, 5-10/LPF). Casts in urine from normal individuals are few or none (and are usually hyaline or granular in nature). An absence of casts does not rule out renal disease.


2 Answers

You might want to consider using the [U]INT<n>_C macros from stdint.h instead (you may need to scroll down to where it says "Macros for Integer Constant Expressions").

The main advantage of these macros, over casts, is that constants defined with them are usable in more contexts. For instance, ((uint32_t)1234) cannot appear in an #if expression, but UINT32_C(1234) can.

Note that most C compilers will not complain about assignments of a constant expression that involve a narrowing conversion, unless the conversion actually changes the value. For instance, given

short a = 1234UL;
short b = ((unsigned long)1234);
short c = 65537UL;
short d = ((unsigned long)65537);

gcc 4.9 and clang 3.5 issue diagnostics about the conversion only for c and d, even when I crank the warnings up as high as they will go.

like image 96
zwol Avatar answered Nov 05 '22 07:11

zwol


I'd consider this a good thing to do, especially ensuring the correct signedness (for this purpose, 1000u would be enough, though). Arithmetic types aren't strongly typed in C, so most code wouldn't change semantics if the macro expansion has the correct signedness and is promoted (that is, not smaller than int).

There are static analysers and options for compilers, however, which do some more type checking and disallow certain implicit conversions, where it would be nice if your constants behaved as if they were variables for most purposes for the code using your header.

like image 41
mafso Avatar answered Nov 05 '22 05:11

mafso