1

When i attempted to implement min function in C as C lacks this function the compiler gives an error. I've used type of for implementing it just like this

MIN and MAX in C

My code

For quick reference:

>#define min(a,b) \
  ({ typeof (a) _a = (a); \
  typeof (b) _b = (b); \        //Min defined
  _a < _b ? _a : _b; })
  .
  .
  .
  c= min(c+floor(1.0/f), bi.biWidth) ;
  r= min(r+floor(1.0/f),abs(bi.biHeight)) ;

Error generated:

 >make resize
 clang -fsanitize=integer -fsanitize=undefined -ggdb3 -O0 -std=c11 -Wall       
 -Werror -Wextra -Wno-sign-compare -Wshadow    resize.c  -lcrypt -lcs50      
 -lm  -o resize

resize.c:191:18: error: implicit declaration of function 'typeof' is    
invalid in C99 [-Werror,-Wimplicit-function-declaration]
          c= min(c+floor(1.0/f), bi.biWidth) ;
             ^
resize.c:11:6: note: expanded from macro 'min'
({ typeof (a) _a = (a); \
 ^
 resize.c:191:18: error: expected ';' after expression
 resize.c:11:17: note: expanded from macro 'min'
 ({ typeof (a) _a = (a); \
            ^

 resize.c:191:18: error: use of undeclared identifier '_a'

 resize.c:11:17: note: expanded from macro 'min'
 ({ typeof (a) _a = (a); \
            ^

 resize.c:191:18: error: expected ';' after expression

 resize.c:12:18: note: expanded from macro 'min'
  typeof (b) _b = (b); \

                  ^

 resize.c:191:18: error: use of undeclared identifier '_b'

 resize.c:12:18: note: expanded from macro 'min'
  typeof (b) _b = (b); \
             ^

 resize.c:191:18: error: use of undeclared identifier '_a'

 resize.c:13:5: note: expanded from macro 'min'
 _a < _b ? _a : _b; })
 ^

 resize.c:191:18: error: use of undeclared identifier '_b'

 resize.c:13:10: note: expanded from macro 'min'
 _a < _b ? _a : _b; })
     ^

 resize.c:191:18: error: use of undeclared identifier '_b'

 resize.c:13:20: note: expanded from macro 'min'
 _a < _b ? _a : _b; })
               ^

 resize.c:193:13: error: expected ';' after expression
     r= min(r+floor(1.0/f),abs(bi.biHeight)) ;
        ^

 resize.c:11:17: note: expanded from macro 'min'
  ({ typeof (a) _a = (a); \
            ^

 resize.c:193:13: error: use of undeclared identifier '_a'

 resize.c:11:17: note: expanded from macro 'min'
 ({ typeof (a) _a = (a); \
            ^

 resize.c:193:13: error: expected ';' after expression

 resize.c:12:18: note: expanded from macro 'min'
  typeof (b) _b = (b); \
             ^

 resize.c:193:13: error: use of undeclared identifier '_b'

 resize.c:12:18: note: expanded from macro 'min'
  typeof (b) _b = (b); \
             ^

 resize.c:193:13: error: use of undeclared identifier '_a'

 resize.c:13:5: note: expanded from macro 'min'
 _a < _b ? _a : _b; })
 ^

 resize.c:193:13: error: use of undeclared identifier '_b'

 resize.c:13:10: note: expanded from macro 'min'
 _a < _b ? _a : _b; })
     ^

 resize.c:193:13: error: use of undeclared identifier '_b'

 resize.c:13:20: note: expanded from macro 'min'
 _a < _b ? _a : _b; })
               ^

 15 errors generated.
Prabhat Sharma
  • 76
  • 1
  • 12

1 Answers1

1

It should be:

#define min(a,b) \
   ({ __typeof__ (a) _a = (a); \
      __typeof__ (b) _b = (b); // Min defined \
      _a < _b ? _a : _b; })

Your comment should not be after the \ but before it. Also you write typeof without the underscores. It is recommended to use them, the explanation is given here at SO.

typeof(), __typeof__() and __typeof() are compiler-specific extensions to the C language, because standard C does not include such an operator.


Macro without typeof:

If your compiler does not support the typeof "operator", you could define the min macro without typeof:

#define min(a,b) (((a) < (b)) ? (a) : (b))

But with that you will have side effects when using postfix or prefix in/decrement operators on variables, because a double evaluation will occur.


Inline function:

The other possibility to make it safe is an inline function. It will be typesafe and no double evaluation will happen:

inline int min(int a, int b)
{
   if (a < b)
   {
      return a;
   }
   return b;
}

You loose type genericity, but there is no other way. You could also think of using double since integers will be implicitly casted. But remember the loose of precision.

Andre Kampling
  • 5,476
  • 2
  • 20
  • 47