News for hackers. Stuff that matters.
Re:The joy of max() by RcouF1uZ4gsC on Friday March 30, 2018 @06:25PM (#16720332)
This is why C++ is so nice. Constexpr fits the bill perfectly instead of using these non-portable hacks.
Re:The joy of max() by tbodt on Friday March 30, 2018 @06:49PM (#16720467)
> In fact, in Linux we did try C++ once already, back in 1992.

> It sucks. Trust me - writing kernel code in C++ is a BLOODY STUPID IDEA.

https://lkml.org/lkml/2004/1/20/20

Re:The joy of max() by AceJohnny2 on Friday March 30, 2018 @07:28PM (#16720644)
A 14-year old opinion based on a 26-year old experiment.

C++ has evolved tremendously since. There are better arguments.

(and I say this as a C developer who doesn't believe C++ is the right answer)

Re:The joy of max() by rileymat2 on Friday March 30, 2018 @09:19PM (#16721096)
With no solid ABI it is unlikely.
Re:The joy of max() by anarazel on Friday March 30, 2018 @09:26PM (#16721111)
Is that a likely problem for the kernel, actually? Given that there's no API stability, and the fact that syscalls are an explicit ABI anyway, I don't see how that'd matter for linux?

(not that I'm arguing for C++ in linux or such)

Re:The joy of max() by ihalip on Saturday March 31, 2018 @04:53AM (#16722434)
When using C++, you also need to take into account the compiler ABI.
Re:The joy of max() by clappski on Saturday March 31, 2018 @10:38AM (#16723461)
Does that really matter in the context of the Linux kernel, seeing as GCC is the only supported compiler currently?
Re:The joy of max() by rileymat2 on Friday March 30, 2018 @09:29PM (#16721118)
Sorry, Just my sour grapes.

Recently created a third party SDK DLL in c++ and could not pass c++ types natively (unless you coupled to compiler and maybe version of compiler).

Re:The joy of max() by gmueckl on Saturday March 31, 2018 @05:56AM (#16722621)
This is C++ on Windows for you. On Linux, most compilers follow the ABI that GCC created, which has become very stable. I actually cannot name a C++ compiler that doesn't follow that ABI.
Re:The joy of max() by cesarb on Saturday March 31, 2018 @09:55AM (#16723288)
Actually, Linux nowadays uses the Itanium C++ ABI (even on non-IA64 architectures), and AFAIK it was created by Intel, not GCC.
Re:The joy of max() by gmueckl on Saturday March 31, 2018 @11:37AM (#16723703)
I stand corrected. Indeed, the Itanium ABI defined by Intel is the base.

The important part is that it is used by most, if not all, C++ compilers on that platform.

Re:The joy of max() by pjmlp on Saturday March 31, 2018 @04:01PM (#16724901)
Which is why any Windows developer that wants to export OO libraries uses COM instead, with the benefit that any Windows compiler that can speak COM is able to use the library.

UWP now even supports generics and actual inheritance.

Re:The joy of max() by garmaine on Saturday March 31, 2018 @03:37AM (#16722240)
Kernel modules?
Re:The joy of max() by jjnoakes on Friday March 30, 2018 @09:38PM (#16721154)
One can use the C ABI with C++.
Re:The joy of max() by Buge on Friday March 30, 2018 @11:02PM (#16721440)
How does that work with templates, overloading, operators, etc?
Re:The joy of max() by loeg on Friday March 30, 2018 @11:21PM (#16721498)
They aren't exposed to ABI surfaces. Only C compatible stuff would be.
Re:The joy of max() by ygra on Saturday March 31, 2018 @02:53AM (#16722131)
Cf. e.g. Microsoft's CRT implementation, which uses C++ by now, but still exposes a C API.
Re:The joy of max() by pjmlp on Saturday March 31, 2018 @03:59PM (#16724883)
On Windows that ABI is COM, on Windows 10 it was updated to UWP and is quite feature rich, even if it doesn't support 100% C++ features.
Re:The joy of max() by RcouF1uZ4gsC on Friday March 30, 2018 @07:36PM (#16720682)
This was 14 years ago. In that time

* C++ has advanced considerably, and features like constexpr, lambas, unique_ptr, etc make writing code easier without runtime overhead.

* The C Compiler that Linux uses, is now written in C++

* Clang tidy checks make it relatively easy to keep problematic C++ features out.

The fact that C++ is largely a superset of C means that just like GCC did, there can be a gradual migration of code.

Re:The joy of max() by userbinator on Friday March 30, 2018 @08:07PM (#16720823)
C++ has advanced considerably

...and gained considerable complexity in the process. (I'm aware that C has gained some too, but not to the extent of C++.)

Re:The joy of max() by ovao on Friday March 30, 2018 @10:44PM (#16721381)
It's a true statement that C++ has gained considerable complexity since those days, largely due to the C++ committee's very religious approach to compatibility. How that added complexity has influenced how complex C++ applications must be is a discussion with considerably more nuance.
Re:The joy of max() by netheril96 on Saturday March 31, 2018 @02:27AM (#16722047)
C language is simple, and the result is this considerably complex piece of implementation instead.
Re:The joy of max() by mehrdadn on Friday March 30, 2018 @09:10PM (#16721065)
And I'd wager the Linux kernel has become more complex in the past couple decades too. But so what?
Re:The joy of max() by okket on Saturday March 31, 2018 @09:53AM (#16723279)
I'd argue: Yes, this is true. But you need at least on stable part in the toolchain for the kernel to get reliable results. You can't have your hammer transform to a screwdriver just because you swing it in the other direction. And if there is such a tool/case, you need to be absolutely sure how and when it behaves this way, on every possible platform.

This is not the case for evolving C++.

Re:The joy of max() by mehrdadn on Saturday March 31, 2018 @04:01PM (#16724897)
To me this situation is more more like having a screwdriver that can only be screwed with hammers from a particular manufacturer (Linux -> GCC), because that manufacturer is the only one that makes hammers with screw-driving tips that work with that particular screw head (non-portable macros for type-checking or whatever goes on there). You might as well just get a normal screwdriver (C++ compiler) and a normal screw (C++ program) like the rest of the world does -- and there's no implication that you have to keep changing screw tips (-std=c++??) every time Apple (standards committee) decides to come up with a new format (C++17).
Re:The joy of max() by JdeBP on Monday April 02, 2018 @09:34AM (#16734305)
If you are going to argue that, then you need to look again at the headlined item, where it was not the case that it behaved the same on every possible platform. It is a non-standard mechanism of one compiler, that was picked based upon a compromise decision about what versions even of that one compiler it would actually work with.
Re:The joy of max() by iforgotpassword on Saturday March 31, 2018 @09:38AM (#16723236)
The problem is that you can't always require people to use the latest bleeding edge version to build your code. Especially the Linux kernel has quite some requirements for backwards compat.

And yes, the fact that abi stability isn't really a thing in c++ land is a huge problem too. It has been tried before with beos and it sucked.

Re:The joy of max() by Animats on Friday March 30, 2018 @06:53PM (#16720481)
Look up the source code for "max" in C++. It's huge.
Re:The joy of max() by edflsafoiewq on Friday March 30, 2018 @07:08PM (#16720552)
This?

    template<typename _Tp>
      _GLIBCXX14_CONSTEXPR
      inline const _Tp&
      max(const _Tp& __a, const _Tp& __b)
      {
        // concept requirements
        __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
        //return  __a < __b ? __b : __a;
        if (__a < __b)
          return __b;
        return __a;
      }
I mean, there are more overloads, but it isn't what I'd call huge.
Re:The joy of max() by gerdesj on Friday March 30, 2018 @07:36PM (#16720679)
Would that thing return precisely the same output for all possible inputs as the new Linux max()? I would imagine that even if the answer was yes, it would also require quite a few provisos.

To be honest, I'm just a bystander here but I did actually find the C based max() presented easier to appreciate than the C++ one you present here.

The C one looks more like a maths proof: build the argument ... et voila. It also does not have comments inline because it is a sort of comment. The C++ version has two inline comments, one of which is incorrectly formatted (space or no space after indicator) and the second one seems superfluous because it uses code to describe code. The C++ version, after you strip out the comments, looks very concise. If it does the same job then good stuff. After that we are down to whether x,y is a better choice than a,b. On balance I prefer a,b for arbitrary inputs and x,y etc for functional dependent - so the C++ example wins here for me.

Re:The joy of max() by minitech on Friday March 30, 2018 @11:08PM (#16721466)
> The C++ version has two inline comments, one of which is incorrectly formatted (space or no space after indicator)

It’s not unusual to use a space after // for comments and no space for code that has been commented out.

Re:The joy of max() by tedunangst on Friday March 30, 2018 @07:44PM (#16720719)
> The C++ version has two inline comments, one of which is incorrectly formatted

This seems like the kind of thing which is easily corrected and probably not relevant for determining which is the better approach.

Re:The joy of max() by ovao on Friday March 30, 2018 @10:46PM (#16721388)
To be pedantic, note that is not the "C++ version" of max(). This is a particular STL's implementation of max(). Different STL implementations may approach it somewhat differently.

In practice, the style for writing STL code is often quite ugly (sometimes deliberately ugly), for reasons which aren't really interesting to most people.

Re:The joy of max() by kzrdude on Saturday March 31, 2018 @03:03AM (#16722156)
It is interesting, it is related to this downside of C++ that templates have to be defined in header files, instead of say being compiled in some kind of module.
Re:The joy of max() by gerdesj on Friday March 30, 2018 @08:16PM (#16720867)
Yes it is easily fixed but this is a lack of attention to detail in a fundamental area. I would imagine that many, many people have seen that code at some point and yet have not bothered to fix up a glaringly obvious formatting error. That may say more about people than the quality of the code but it looks awful to an outsider (like me).

That chunk of code is one of the fundamental building blocks of C++. When presented as exhibit A it should look good. To an outsider that sort of thing looks bad, even if the presented thing is correct the silly error will be obsessed over - as here.

If something is important enough, and I think that C++ is one of those, then for $DEITYS sake fix the obvious stuff before having to be an apologist for it. A simple sed script run decades ago would have done that.

The reason I am labouring this point is that one day it wont be a discussion on HN debating this sort of bollocks but something involving lots of dosh. If S&M ever realised what source code really looked like - they'd have a fit. The world turns ...

Re:The joy of max() by tedunangst on Saturday March 31, 2018 @12:22AM (#16721710)
I'm going to have to disagree that a missing space in a comment is a fundamental flaw.
Re:The joy of max() by wruza on Saturday March 31, 2018 @10:53AM (#16723537)
Argh, I deserve my portion of lashes, but it is so clearly standing in my experience: most coders who don’t care of syntactical purity like formatting, indenting, consistency, meaningfulness etc. — they have less awareness and make more errors than those who do. It is not a strict rule, but a sign of weakness in that regard.

  }
  int foo(){
    for(x=1; x<len*2;x++){//over 2 array len
    ...(no empty lines for next hour)
I know I’m clinical perfectionist, but try to see it behind my complaint. Our brain can process only few things in parallel. If you overload it with parsing and do not provide hints like grouping and/or formatting, you occupy a couple of threads for a complete bs. As if programming was not one of the hardest things already.
Re:The joy of max() by kcanini on Saturday March 31, 2018 @12:07AM (#16721674)
Have you considered that it might be intentional?
Re:The joy of max() by setzer22 on Saturday March 31, 2018 @11:55AM (#16723780)
I agree. This looks to me like a commented out source line, not a comment that describes what comes next using a similar code expression.

It makes sense to drop the space before the start of the commented code because that way you can just delete the // and obtain the original source line.

Re:The joy of max() by anonymouz on Saturday March 31, 2018 @10:22AM (#16723398)
You are upset about comment formatting, but find this easier to appreciate?

  ...
  #define __is_constant(x) \
      (sizeof(int) == sizeof(*(1 ? ((void*)((long)(x) * 0l)) : (int*)1)))
  ...
How many C programmers would even understand what that code does, without an explanation?
Re:The joy of max() by RcouF1uZ4gsC on Saturday March 31, 2018 @01:11PM (#16724113)
And it is not even standard C, but uses GCC extensions.
Re:The joy of max() by loeg on Friday March 30, 2018 @11:26PM (#16721519)
Does this coerce distinct type a and b, or just fail if they are different types? The C one will evaluate the comparison / trinary expression via the usual integer promotion rules.
Re:The joy of max() by gmueckl on Saturday March 31, 2018 @06:02AM (#16722637)
The C++ version does not promote types. The language is generally much stricter about implicit type conversions, so this is very much in line with the language design.
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".
Re:The joy of max() by eigenbom on Friday March 30, 2018 @07:51PM (#16720757)
In libcxx it's a few lines. Unless you also count the overloads for initialiser_list etc.