News for hackers. Stuff that matters.
Re:The joy of max() by smitherfield on Friday March 30, 2018 @07:44PM (#16720715)
For Linux kernel purposes the following one-liner would suffice

    template<class T> constexpr T max(T l, T r) {return l < r ? r : l;}
Re:The joy of max() by dawg on Friday March 30, 2018 @10:05PM (#16721253)
And this short snippet in D

    T max(T)(T a, T b) { return a < b ? b : a; }
without requiring explicit constexpr annotations and with less noisy template syntax ;).
Re:The joy of max() by smitherfield on Friday March 30, 2018 @11:39PM (#16721575)
Does it compile the Linux kernel? ;)
Re:The joy of max() by loeg on Friday March 30, 2018 @11:25PM (#16721515)
The C version works with distinct types for a and b. Does this?
Re:The joy of max() by smitherfield on Friday March 30, 2018 @11:36PM (#16721558)
No it doesn't, which is one of the major advantages it has over the C version; you have to do an explicit cast when the args are different types (almost always a potential source of subtle bugs).

Or what edflsafoiewq said: https://news.ycombinator.com/item?id=16721559

It is however trivial to write a version that works with distinct types, if that were really what you want.

  template<class L, class R>
  constexpr std::common_type_t<L, R> max(L l, R r) {return l < r ? r : l;}
Re:The joy of max() by Too on Saturday March 31, 2018 @02:46AM (#16722117)
Assuming the single template argument version. If T has an implicit constructor taking type R as argument, wouldn't the second argument into max of type R be implicitly converted to T before getting passed to the max function? So there is no need for a special version taking both L and R?

This is a property of c++ implicit constructor rules, it is not unique to this function. In most cases this is something you want to avoid but for integer promotion it can some times be useful.

Re:The joy of max() by smitherfield on Saturday March 31, 2018 @03:17AM (#16722200)
Nope, template type deduction never implicitly converts: https://godbolt.org/g/stZBK1
Re:The joy of max() by Too on Saturday March 31, 2018 @03:41AM (#16722255)
Oh, "conflicting types for parameter 'T' ('T2' vs. 'T1')". I'm surprised but it's a nice surprise. Finally something in c++ where safety is valued more than implicit dangerous magic.
Re:The joy of max() by bstamour on Saturday March 31, 2018 @08:07AM (#16722944)
C++'s type system has always been stricter than C's. Even the following, totally valid C program, is ill-formed C++

    int* x = malloc(5 * sizeof (int));
because in C++ you cannot implicitly cast a void pointer.
Re:The joy of max() by edflsafoiewq on Friday March 30, 2018 @11:36PM (#16721559)
You'll have to give the template parameter explicitly, like

    max<int>(-1, 2u) // => 2
Re:The joy of max() by ploxiln on Friday March 30, 2018 @08:16PM (#16720871)
A difference is that the linux macro works for non-constant expressions as well.

All the crazyness is in order to support both constant expressions (and keep them constant expressions) and non-constant expressions with the same max() macro.

Re:The joy of max() by andrepd on Friday March 30, 2018 @08:36PM (#16720951)
That version does this. From cppreference (emphasis mine):

>The constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time. Such variables and functions can then be used where only compile time constant expressions are allowed (provided that appropriate function arguments are given).

Re:The joy of max() by smitherfield on Friday March 30, 2018 @08:22PM (#16720905)
That one-liner I posted works with both constant and non-constant expressions (and in fact is more likely to be evaluated at compile-time than the macro), is type-safe, and has no side effects assuming both arguments are arithmetic types or pointers (like all uses of `max` in the Linux kernel / C-language programs).
Re:The joy of max() by ovao on Friday March 30, 2018 @10:52PM (#16721399)
In C++, all the craziness and brittleness you find in the "C version" is actually encompassed entirely within the `constexpr` keyword. The compiler gets to deal with a lot of complexity to make that possible, but for users it is genuinely "that easy".