min
函数的经典预处理器版本看起来像
#define min(a, b) ((a) < (b) ? (a) : (b))
这使你可以进行双重评估 – 你做min(f(), g())
,忘记f
或g
有副作用,你必须花费数小时试图找出你的函数运行两次的原因。 为了防止这种情况,你可以做到
#define min(a, b) ({__typeof__(a) _a = (a); __typeof__(b) _b = (b); _a < _b ? _a : _b;})
这在GCC下工作得很好,但是如果你通过-Wgnu
设置的Clang运行它 – 这组警告属于-pedantic
的保护伞 – 你会得到像
test.c:5:10: error: use of GNU statement expression extension [-Werror,-Wgnu] int a = min(3, 7); ^ test.c:1:22: note: expanded from macro 'min' # define min(a, b) ({__typeof__(a) _a = (a); __typeof__(b) _b = (b); _a < _b ? _a : _b;})
是否有可能以防止双重评估的方式定义这些宏, 并且可以接受Clang under -pedantic
? (是的,你可以用-Wno-gnu
禁用警告,在这种情况下,Clang处理语句表达没有问题。我问,因为我像clang -pedantic
,对我自己的好处太挑剔了。)
编辑:我在C工作。我也标记了这个C ++,因为我认为解决方案可能适用于C ++以及C.哎呀 – 忘了模板! 抱歉模棱两可。
如果你真的用C ++编写,那么就不要使用预处理器 :
template const T min(const T& a, const T& b) { return (b < a) ? b : a; }
(注意我已经交换了b
和a
,所以如果两者相等,你就得到左手操作数。)
否则不,不是真的 。
我认为这可以作为C11解决方案。
inline int min(int const x, int const y) { return y < x ? y : x; } inline unsigned minu(unsigned const x, unsigned const y) { return y < x ? y : x; } inline long minl(long const x, long const y) { return y < x ? y : x; } inline unsigned long minul(unsigned long const x, unsigned long const y) { return y < x ? y : x; } inline long long minll(long long const x, long long const y) { return y < x ? y : x; } inline unsigned long long minull(unsigned long long const x, unsigned long long const y) { return y < x ? y : x; } inline float minf(float const x, float const y) { return y < x ? y : x; } inline double mind(double const x, double const y) { return y < x ? y : x; } inline long double minld(long double const x, long double const y) { return y < x ? y : x; } #define MIN(X, Y) (_Generic((X) + (Y), int: min, unsigned: minu, long: minl, unsigned long: minul, long long: minll, unsigned long long: minull, float: minf, double: mind, long double: minld)((X), (Y)))
Simple发布的C11解决方案看起来很理想,但是如果你没有C11编译器,你仍然可以定义一个具有内在类型安全性的宏(因为无论如何都像C一样安全):
#define MIN(type, X, Y) min_ ## type(X, Y)
此宏将仅允许传递已实现的类型,否则您将收到编译器错误。
例:
#define MIN(type, X, Y) min_ ## type(X, Y) long min_long (long x, long y); char min_char (char x, char y); float min_float (float x, float y); int main() { long min_l = MIN (long, 5L, 10L); char min_c = MIN (char, 'A', 'B'); float min_f = MIN (float, 666.66f, 3.14f); printf("%ldn", min_l); printf("%cn", min_c); printf("%fn", min_f); } char min_char (char x, char y) { return x < y ? x : y; } long min_long (long x, long y) { return x < y ? x : y; } float min_float (float x, float y) { return x < y ? x : y; }
现在,如果你用MIN(int, 1, 2)
执行上面的宏,你会得到一个编译器错误:“ min_int
,不存在这样的函数”。
需要了解更多c/c++开发分享在没有双重评估的情况下在Clang中实现min()和max(),也可以关注C/ C++技术分享栏目---计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享在没有双重评估的情况下在Clang中实现min()和max()相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979060.html