C语言中的MIN和MAX定义在哪里?

实现这些最好的方法是什么,尽可能的泛型和类型安全?(主流编译器的编译器扩展/内置优先。)


当前回答

这是一个较晚的答案,由于最近的发展。由于OP接受了依赖于不可移植的GCC(和clang)扩展类型的答案-或“干净”ISO C的__typeof__ -在GCC -4.9有一个更好的解决方案。

#define max(x,y) ( \
    { __auto_type __x = (x); __auto_type __y = (y); \
      __x > __y ? __x : __y; })

这个扩展的明显好处是每个宏参数只展开一次,不像__typeof__解决方案。

__auto_type是c++ 11的auto. type的有限形式。它不能(或不应该?)在c++代码中使用,尽管在使用c++ 11时没有很好的理由不使用auto的高级类型推断功能。

也就是说,我假设当宏包含在extern“C”{…}范围;例如,来自C头文件。AFAIK,这个扩展没有找到它的方式信息叮当

其他回答

C语言中的MIN和MAX定义在哪里?

他们不是。

实现这些的最好方法是什么,尽可能的泛型和类型安全(主流编译器的编译器扩展/内置首选)。

作为功能。我不会使用像#define MIN(X, Y) (((X) < (Y))这样的宏?(X):(Y)),特别是如果您计划部署您的代码。要么写你自己的,使用标准的fmax或fmin,或者在GCC语句表达式中使用GCC的typeof(你也会得到类型安全奖励)修复宏:

 #define max(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a > _b ? _a : _b; })

每个人都说“哦,我知道双重求值,这没问题”,几个月后,你会连续几个小时调试最愚蠢的问题。

注意使用__typeof__而不是typeof:

如果你正在写一个头文件 必须工作时,包括在ISO C 程序,写__typeof__而不是 typeof。

我编写的这个版本适用于MSVC、GCC、C和c++。

#if defined(__cplusplus) && !defined(__GNUC__)
#   include <algorithm>
#   define MIN std::min
#   define MAX std::max
//#   define TMIN(T, a, b) std::min<T>(a, b)
//#   define TMAX(T, a, b) std::max<T>(a, b)
#else
#       define _CHOOSE2(binoper, lexpr, lvar, rexpr, rvar) \
                ({ \
                        decltype(lexpr) lvar = (lexpr); \
                        decltype(rexpr) rvar = (rexpr); \
                        lvar binoper rvar ? lvar : rvar; \
                })
#       define _CHOOSE_VAR2(prefix, unique) prefix##unique
#       define _CHOOSE_VAR(prefix, unique) _CHOOSE_VAR2(prefix, unique)
#       define _CHOOSE(binoper, lexpr, rexpr) \
                _CHOOSE2( \
                        binoper, \
                        lexpr, _CHOOSE_VAR(_left, __COUNTER__), \
                        rexpr, _CHOOSE_VAR(_right, __COUNTER__) \
                )
#       define MIN(a, b) _CHOOSE(<, a, b)
#       define MAX(a, b) _CHOOSE(>, a, b)
#endif

两个整数a和b的最大值是(int)(0.5((a+b)+abs(a-b)))。这也可以用于(double)和fabs(a-b)用于double(类似于float)

我将避免同时将MIN和MAX定义为预处理器宏。 即使改进了实现,避免了双重评估,即。

#define max(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a > _b ? _a : _b; })

当您尝试在函数之外使用此函数(参见这里的示例)或在此答案中引用的变量阴影时,您会遇到其他问题,例如编译器错误。

如果你迫切需要宏所带来的性能优势,即代码内联,可以将它们实现为内联函数。大多数现代编译器都支持内联。比如像这样

inline int32_t MAX(int32_t a, int32_t b) { return((a) > (b) ? a : b); }
inline int32_t MIN(int32_t a, int32_t b) { return((a) < (b) ? a : b); }

(更多)

你必须为你需要的每一种数据类型实现一个变体,但通常你会使用有限的一组数据类型。话虽如此,请记住比较浮点数有它自己的怪癖,你需要比上面更复杂的代码(参见这里的讨论)。

这是一个较晚的答案,由于最近的发展。由于OP接受了依赖于不可移植的GCC(和clang)扩展类型的答案-或“干净”ISO C的__typeof__ -在GCC -4.9有一个更好的解决方案。

#define max(x,y) ( \
    { __auto_type __x = (x); __auto_type __y = (y); \
      __x > __y ? __x : __y; })

这个扩展的明显好处是每个宏参数只展开一次,不像__typeof__解决方案。

__auto_type是c++ 11的auto. type的有限形式。它不能(或不应该?)在c++代码中使用,尽管在使用c++ 11时没有很好的理由不使用auto的高级类型推断功能。

也就是说,我假设当宏包含在extern“C”{…}范围;例如,来自C头文件。AFAIK,这个扩展没有找到它的方式信息叮当