使用 typeof 编译器扩展在 C 中实现 min 函数会出错
Implementing min function in C by using typeof compiler extension gives error
当我试图在 C 中实现 min 函数时,因为 C 缺少此函数,编译器给出了一个错误。我使用 type of 来实现它就像这样
MIN and MAX in C
快速参考:
>#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)) ;
产生错误:
>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.
应该是:
#define min(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); // Min defined \
_a < _b ? _a : _b; })
您的评论应该而不是在\
之后,而是在它之前。
你也写 typeof 没有下划线。推荐使用它们,给出解释here at SO.
typeof()
, __typeof__()
and __typeof()
are compiler-specific extensions to the C language, because standard C does not include such an operator.
没有 typeof 的宏:
如果你的编译器不支持typeof
"operator",你可以定义没有typeof的min宏:
#define min(a,b) (((a) < (b)) ? (a) : (b))
但是,在对变量使用后缀或前缀 in/decrement 运算符时,会产生副作用,因为会发生双重计算。
内联函数:
另一种使其安全的可能性是内联函数。它将是类型安全的,不会发生双重评估:
inline int min(int a, int b)
{
if (a < b)
{
return a;
}
return b;
}
你失去了类型通用性,但别无他法。您还可以考虑使用 double,因为整数将被隐式转换。但请记住精度的松散。
当我试图在 C 中实现 min 函数时,因为 C 缺少此函数,编译器给出了一个错误。我使用 type of 来实现它就像这样
MIN and MAX in C
快速参考:
>#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)) ;
产生错误:
>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.
应该是:
#define min(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); // Min defined \
_a < _b ? _a : _b; })
您的评论应该而不是在\
之后,而是在它之前。
你也写 typeof 没有下划线。推荐使用它们,给出解释here at SO.
typeof()
,__typeof__()
and__typeof()
are compiler-specific extensions to the C language, because standard C does not include such an operator.
没有 typeof 的宏:
如果你的编译器不支持typeof
"operator",你可以定义没有typeof的min宏:
#define min(a,b) (((a) < (b)) ? (a) : (b))
但是,在对变量使用后缀或前缀 in/decrement 运算符时,会产生副作用,因为会发生双重计算。
内联函数:
另一种使其安全的可能性是内联函数。它将是类型安全的,不会发生双重评估:
inline int min(int a, int b)
{
if (a < b)
{
return a;
}
return b;
}
你失去了类型通用性,但别无他法。您还可以考虑使用 double,因为整数将被隐式转换。但请记住精度的松散。