47

I read about the std::abs() function when browsing cppreference.

On that page I have also seen a std::labs() function. Which has the same prototype as one of the std::abs() overloads (the one for long).

long abs( long n );

long labs( long n );

and

long long abs( long long n );

long long llabs( long long n );

So,

  • What exactly std::labs() does?
  • Where and when do I use std::labs()?
  • What is the difference between std::abs() and std::labs()?
msc
  • 33,420
  • 29
  • 119
  • 214

1 Answers1

63

C++11 was when std::labs and std::llabs were added. This was part of the partial syncing done to the C++ standard library with the C99 standard library.

You don't really need it in C++ code, because we had a long overload of std::abs since about forever. But if you have some C code (that by sheer coincidence also compiles with a C++ compiler), and it uses labs, you can build it with a C++11 compiler and standard library.


In retrospect, there is one marginally useful use case for these functions. And that is when an attempt to use std::abs is ambiguous. For instance:

template<typename T>
T run_func(T (&f)(T)) {
  return f({});
}

Then trying to call run_func(std::abs); is ill-formed. We need to either specify the template argument explicitly or cast std::abs to the proper type. On the other hand run_func(std::labs); isn't ambiguous, and not too verbose.

Still, not too useful.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • 6
    Re: "some C code (that by sheer coincidence also compiles with a C++ compiler)": And the award for most gratuitous use of the phrase "sheer coincidence" goes to . . . – ruakh Sep 27 '17 at 17:10
  • 7
    I'm not sure I follow you, @ruakh. It is not to be expected that an arbitrary, but valid, C translation unit can be successfully compiled unmodified as C++, unless it has been intentionally written to support that. Where one can be, that is indeed a coincidence. If such code happens to furthermore have the same semantics in both languages then that's even more of a coincidence. How, then, is the use of the phrase "sheer coincidence" in this answer gratuitous? – John Bollinger Sep 27 '17 at 20:15
  • @JohnBollinger: C++ grew out of C, and has maintained a high degree of backward-compatibility. Furthermore, even in those areas where the C++ standards have *not* maintained compatibility (or where the C standards have since changed and the C++ standards have not followed), C++ compilers often implicitly extend C++ for compatibility with C. As a result, many real-world C programs can be compiled, with no modifications at all, using many real-world C++ compilers. To claim that this is "sheer coincidence" requires willful obtuseness IMHO. – ruakh Sep 27 '17 at 20:52
  • 7
    @ruakh - C++ has broken compatibility from the onset. The simplest (and idiomatic) `int *p = malloc(sizeof *p);` never did and never will compile in C++. And no compiler ever allowed the implicit conversion from `void*` back, to my knowledge. That's to name one example, anyway. Blame me of being obtuse if you will, but I think your argument stems out of an incomplete view of the languages. – StoryTeller - Unslander Monica Sep 27 '17 at 20:56
  • 3
    @ruakh - Furthermore, since the context of my use of the phrase was C99. For the program to be compilable as C++, the person who wrote it would have had to intentionally avoid useful constructs like designated initializers and compound literals. Crippling oneself to be "compatible" with a completely separate language, is unlikely. – StoryTeller - Unslander Monica Sep 27 '17 at 20:58
  • 1
    @StoryTeller C and C++ are not completely separate languages. They are overlapping languages. I feel like what you want to say is that one should not count on the fact that C will compile with a C++ compiler, which is totally right. – Bobsleigh Sep 27 '17 at 21:29
  • 2
    @Bobsleigh - If you compare them based on their philosophies, they don't overlap much at all. They are two languages, governed by two separate ISO committees. And that's not without reason. C++ may care to have some interoperability with C, but it certainly never set out to have its compilers be a drop in replacement for C compilers. – StoryTeller - Unslander Monica Sep 27 '17 at 21:33
  • 2
    @ruakh, just how high is C++'s compatibility with modern C -- or even with C99 -- is a qualitative question that you and I will not settle. I'm not even sure we would agree on how to measure. Ultimately, the point for me is that many people erroneously assume that C++ is a superset of C, and therefore that all C code can safely be compiled as C++. That assumption should be challenged at every opportunity, as it leads to grief, whether sooner or later. I have no objection to StoryTeller engaging in a bit of hyperbole in that pursuit, if that's how you choose to regard it. – John Bollinger Sep 27 '17 at 21:35
  • 2
    As a data point, I'm in the process of converting a relatively small C project (around 10,000 lines) to C++. The first cut was just using a C++11 compiler instead of a C99 compiler and fixing warnings/errors. I'm a fairly aggressive C99 user. The changes I had to make: variables named new, casting *alloc(), static in array sizes in function declarations, compound literals, enum scoping in structs, variable-length arrays, string literals as const char[] vs char[], and designated initializers. It was not a trivial exercise, although it wasn't particularly difficult. – Chris Oct 03 '17 at 08:19
  • I think that's the point -- it's hard to get a non-trivial program that's valid C and C++ accidentally, it takes deliberate work to like that. And the point of reconciling the libraries is presumably to make things a little easier for people who need to do this. It's not for programs that just happen to be lucky. – Barmar Oct 03 '17 at 19:54
  • @Chris did you end up with something that is idiomatic C++? How sure are you that it does what the C version does? – Caleth Oct 05 '17 at 11:03
  • @Caleth No, I didn't wind up with idiomatic C++. I made some fairly large changes, but not architectural ones (e.g. I do some custom I/O stuff; it was an opaque struct in the vein of C's FILE initially, but is now a class). I've decided a ground-up rewrite would be needed for idiomatic C++, but I'm a lot happier now with a sort of hybrid approach. I feel more comfortable using the STL instead of maintaining custom data structures. As for correctness, I have various test data that I can run through the program, and it all passes. Not definitive, but enough to make me confident. – Chris Feb 05 '18 at 19:54
  • @StoryTeller: `return f({});` what it does ? This seems strange syntax. – Destructor Feb 08 '18 at 13:09
  • @Destructor - Depends on T. For a type like long, it value initializes it (to 0). – StoryTeller - Unslander Monica Feb 08 '18 at 13:12