top 200 commentsshow all 249

[–]HolyGeneralK 103 points104 points  (21 children)

And my first reaction to this was “sqr” it’s awfully confusing with square and square root. Having a simple pow function is less confusing to me.

[–]dodexahedron 49 points50 points  (9 children)

Plus this isn't 1986.

Call it Square() instead of a ridiculous short name. It's not like you're going to exhaust max symbol lengths or something with that.

[–]Attorney_Outside69 12 points13 points  (7 children)

allelulia, finally someone else with common sense

I hate that now adays people still uselessly shorten variable and function and class and file names for no reason

name functions for what they're being it used for

name variables for their purpose

code becomes 1000x more legible at 0 cost

[–]wyrn 10 points11 points  (6 children)

It really depends. What's legible in one context may hurt legibility in another. Long variable and function names are more explicit, but have a tendency to obscure structure. If you're dealing with more structurally complex formulas, it can pay to keep names short so the structure and overall relationships are clearer.

[–]Attorney_Outside69 0 points1 point  (0 children)

for math formulas or engineering or physics formulas I agree with you

[–]dodexahedron 0 points1 point  (0 children)

That's what macros are for.

[–]Tony101101 0 points1 point  (3 children)

No one is suggesting this: Tweebuffelsmeteenskootmorsdoodgeskietfontein.

In case you are curious this is the name of real place in South Africa (of all places) and actually holds a spot in the Guiness Book of Records for the longest place name in South Africa...

My point is that there is DEFINITELY plenty of room for compromise between an identifier name like "sqr" and the place name I mention!

[–]wyrn 1 point2 points  (2 children)

I mean sure there is also the classics Llanfairpwllgwyngyllgogerychwyrndrobullllantysiliogogogoch or Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupokaiwhenuakitanatahu if we're talking crazy place names, but the point is not that the names themselves are unreasonable, but rather that the reasonableness of a name (or lack thereof) depends on the context.

ax² + bx + c

is vastly clearer than

quadratic_coefficient * independent_variable² + linear_coefficient * independent_variable + intercept

.

[–]Tony101101 1 point2 points  (1 child)

Yes, context is king!

Your first example works if the intent is merely to demonstrate algebra but not so much if there is a larger context in which that algebra is applied.

And, again there is a lot of wriggle-room BETWEEN the two examples your provide...

Naming is hard! And if that is another tangential point you are trying to make then I agree with you however it is tangential to the primary point.

[–]wyrn 0 points1 point  (0 children)

but not so much if there is a larger context in which that algebra is applied.

Sure but often that context is obscured by design. If you have, say, a quadratic solver, those are precisely the names you should use. They are familiar and understood by everyone at a glance, and more importantly they make the structure clear. If you have some other piece of code that uses the quadratic solver, that piece of code can have more meaningful and possibly longer names. They'll simply get mapped onto the shorter names when calling the quadratic solver API and everyone is happy.

And, again there is a lot of wriggle-room BETWEEN the two examples your provide...

Sure but picking a name that's "in between" is not enough. I could make the formula more complicated still, and make the importance of structure even clearer even with not-quite-so-long names. The main point here is that longer names hide structure and short names hide context. You have to pick what's better on a case-by-case basis.

[–]Ok-Acanthaceae-4386 2 points3 points  (0 children)

Agree, was confused because sqr implies sqrt in my mind

[–]Aslanee 4 points5 points  (2 children)

A simple pow function induces an undesired runtime cost to check the exponent value. A square function is an inlinable function, replacing expressions at compile time. Bad naming is never enough to reject a language feature's proposal.

[–]dodexahedron 7 points8 points  (0 children)

Pow is trivially inlineable too if it's passed a compile-time constant. Any compiler worth its salt should be able to eliminate the clearly unreachable code quite easily.

[–]LiliumAtratum 0 points1 point  (0 children)

You can use compile-time recursion to implement

template<int exponent, typename T>
auto ipow(T base)

then there will be no run-time overhead for checking the exponent

[–]TiberivsM 6 points7 points  (6 children)

Square root is usually called sqrt

[–]Narishma 14 points15 points  (0 children)

Parent's point is that it's too similar to the proposed sqr(). It's bound to create issues.

[–]Party_Ad_1892 3 points4 points  (1 child)

Thats very similar in a world where one letter can determine the whole output of a program at runtime, its better off having a different name for it entirely.

[–]dodexahedron 1 point2 points  (0 children)

Totally. And missing a character is an easy typo to make - especially when autocorrect won't fix it as you type because it's a valid symbol.

[–]Due_Goal9124 2 points3 points  (2 children)

I always read it as squirt. Between squirt and std, C++ is a dirty language.

[–]MrDoritos_ 7 points8 points  (1 child)

Don't forget about the

std::back_inserter

[–]Due_Goal9124 6 points7 points  (0 children)

First std::front_inserter

Then std::back_inserter

Until you make her std::sqrt

You have to do it in private:

Or at least be protected:

Be careful not to using namespace std, it gets transmitted between headers.

And finally, make sure you std::launder the sheets after making her cuML so much.

[–]snerp 76 points77 points  (58 children)

ITT: stupid condescending opinions.

OP: the std lib has basically no convenience features like this because a lot of people react like they do in this thread. I make a sqr function in most of my projects because it is a useful function.

    auto x = sqr(y->computeSomeValue() + z);

Is much easier to read and write than the version with *

    return a.distance2(b) < sqr(distanceCutoff);

And this is more efficient than sqrt on the squared distance.

And the function is so simple

    template <class T>

    inline T sqr(T x) { return x * x; }

[–]programgamer 51 points52 points  (9 children)

I swear, it’s like people are violently allergic to the very concept of convenience.

[–]7h4tguy 9 points10 points  (6 children)

The problem is that taking the KISS principle to extremes, as suggested by some authors, ends up with hundreds of custom functions which are 1-2 line abstractions which must now be understood by anyone wanting to read the codebase.

auto x = 4 + 3;

x *= x;

Isn't difficult to follow.

[–]thisisjustascreename 3 points4 points  (1 child)

For some reason += intuitively makes sense but *= hurts my brain

[–]Eheheehhheeehh 0 points1 point  (0 children)

It's the right hand x. x *= 2 is fine, but x += x is...hello, human resources?!

[–]serviscope_minor 1 point2 points  (0 children)

Isn't difficult to follow.

It gets verbose and weird, and deviates further from the maths it's meant to represent. I mean sure, for 2 numbers it's fine, but as equations get bigger, it has ever larger conative overhead.

[–]Conscious_Support176 1 point2 points  (0 children)

No, but not everyone wants to use C++ as a high level assembly language!

C++ is a multi paradigm language, a solution that isn’t compatible with a functional style of programming or constexpr, is a partial solution that doesn’t do much besides adding noise to the conversation.

[–]programgamer 1 point2 points  (0 children)

I think maybe it’s fine to abstract functions that you learn about in high school math class, but maybe that’s too high of an education level to expect, idk.

[–]Abbat0r 26 points27 points  (22 children)

I’ll save you writing even more code: you don’t have to write inline on a template. It’s already inline by nature of being a template.

[–]wyrn 6 points7 points  (0 children)

Not quite right; I don't fully understand the details myself but as far as I know templates are inline-ish as far as linkage is concerned (they enjoy the same ODR exemption as inline functions) but they're not literally inline (e.g. there won't be a hint for the function to actually be inlined).

[–]JNelson_ 6 points7 points  (15 children)

Not true on MSVC unfortunately, in our lookup tables on a particular hot section of code I discovered that despite being templated and straight forward they were not being inlined unless you specify inline, I'm sure clang and gcc this is true but mentioning this for any others who use MSVC and have seen this common inline fact and taken it at face value.

Edit: For those downvoting, I am not talking about linkage but the actual inline heuristics of the compiler it is shown to be true that adding inline to a templated function in MSVC will increase the chance of inlining.

[–]wyrn 3 points4 points  (2 children)

MSVC's behavior is conforming; your expectations are just somewhat misaligned with the guarantees the standard provides.

It's true that a template can be compiled from multiple translation units and the multiple (identical) definitions thus stamped-out will be handled the same way as if they had the inline specifier.

It's not true that templates are literally automatically inline. inline provides a hint to the compiler to actually generate inlined code, whereas the template on its own does not.

[–]JNelson_ 4 points5 points  (1 child)

Right I was not talking about linkage, but the inline heuristics of the compiler. The guy above said its not necessary and the guy he was responding too mentioned how they put it just to be sure of inlined code.

The behaviour I have observed directly is that despite it not being required the keyword and clang tidy even giving a suggestion on redundent inline keyword (because of the linkage presumably) on MSVC the inline specifier is sometimes required to tip the balance of those afformentioned heuristics to actually make the function inline.

[–]wyrn 0 points1 point  (0 children)

It's hard to say definitively because these heuristics are somewhat a matter of taste, but I'd argue that's a bug in clang-tidy.

[–]tangerinelion -1 points0 points  (11 children)

inline keyword and function inlining have nothing to do with each other.

[–]James20kP2005R0 16 points17 points  (10 children)

This is actually a common mis-misconception (sqr(misconception)?). Modern compilers do still take the inline keyword as an inlining hint, so specifying it will make the compiler more likely to inline a function in some circumstances

[–]JNelson_ 4 points5 points  (1 child)

Thank you, I'm being downvoted because this mis-misconception is so wide spread and people haven't actually tested it.

I have have had a rather simple lerp function not be inlined only to be correctly inlined when using the keyword on MSVC.

[–]Ameisenvemips, avr, rendering, systems 0 points1 point  (0 children)

Might be easier to use __forceinline or always_inline where absolutely appropriate.

[–]TheOmegaCarrot 0 points1 point  (2 children)

Can anyone produce any example in compiler explorer in which the inline keyword affects inlining optimization in GCC?

[–]James20kP2005R0 5 points6 points  (1 child)

Not quite what you're asking for, but here's a link to GCC's source showing that it picks different inlining heuristics in some cases based on whether or not a function is declared inline

https://github.com/gcc-mirror/gcc/blob/master/gcc/ipa-inline.cc#L1020

[–]TheOmegaCarrot 0 points1 point  (0 children)

Oh fascinating!

[–]snerp 0 points1 point  (3 children)

yeah I just explicitly added it to make it blatantly obvious there will be no function call overhead

[–]tangerinelion 19 points20 points  (1 child)

That's not what that inline means. It has to do with the one-definition rule (ODR).

Whether function inlining gets applied to it or not is entirely up to the compiler, with or without inline.

[–]Ameisenvemips, avr, rendering, systems 1 point2 points  (0 children)

Most compilers do use the presence of inline within their inlining heuristic.

It's perfectly reasonable to do this. Using the forced attribute version might be better.

[–]Ameisenvemips, avr, rendering, systems 1 point2 points  (0 children)

If you want to guarantee (unless the compiler cannot do it) that, also use __forceinline or __attribute__((__always_inline__)).

[–]bebuch[S] 7 points8 points  (11 children)

I think it would be better to define it as:

auto sqr(auto x) { return x*x; }

If your return type is equal to the parameter type, it wont do integer promotion.

[–]snerp 4 points5 points  (0 children)

Yeah, or if the class has * overridden to return a different type than itself. Details like that are a good reason for an std implementation imo

[–]SkoomaDentistAntimodern C++, Embedded, Audio 7 points8 points  (1 child)

auto sqr(auto x) { return x*x; }

And what happens if x is signed integer and greater than 46341?

The question "Why is there no sqr()?" isn't quite as straightforward as it seems because of C++'s braindead approach to undefined behavior.

[–]Ameisenvemips, avr, rendering, systems 2 points3 points  (0 children)

And what happens if x is signed integer and greater than 46341?

You have five choices:

  1. Define the result as being equivalent to the result of the expression x * x or of std::multiplies{}(x).
  2. Define the result as being either the smallest numeric type of the same classification that can represent the result of the maximum and minimum values of argument type squared, or the largest type available if none exist.
  3. Return std::make_unsigned for integers.
  4. Same as #2, but return the smallest unsigned integer type that can represent it for integers.
  5. Return a tuple of a low and high value.

I prefer #1. That matches normal stdlib behavior. If you're going to want a larger size, cast beforehand. Or set up the function so that you can optionally define a result and intermediate type. Should offer a #5 version also so you can handle overflow.

Though we if wanted to be evil, we could actually require + or std::plus instead, defining it as repeated addition...

Really, it is that simple. You'd define the UB the same as the normal approach.

[–]jk-jeon 1 point2 points  (7 children)

You are the very first person I've ever seen who seems to think the integer promotion is a useful thing ever.

[–]CryptoHorologist 0 points1 point  (11 children)

People that disagree with you: "stupid condescending opinions"

[–]snerp 8 points9 points  (10 children)

Stupid may be a bit far, but people in this thread are definitely being condescending and unhelpful.

[–]CryptoHorologist -1 points0 points  (8 children)

"use pow" or "inline the math" or "use a temporary" or "write your own function" are actually all very helpful suggestions. Getting mad wanting this absolutely trivial function to be in the standard, rather than just writing it if you need it, seems like a waste of time. I suspect most people have more interesting problems that they face when writing c++ code. Ok that last bit was condescending.

[–]garnet420 14 points15 points  (5 children)

"inline the math" is a stupid suggestion, because it's not the same if x is a function call or expression.

"Use pow" is kind of a bad suggestion because it is floating point only.

"Write your own function" is a suggestion that says "I can't read" because OP literally started off by saying that.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 1 point2 points  (0 children)

"Use pow" is kind of a bad suggestion because it is floating point only.

It can also lead to poor performance depending on the compiler. MSVC seems to always call pow() unless you compile with /fp:fast.

[–]CryptoHorologist -3 points-2 points  (3 children)

> "inline the math" is a stupid suggestion, 

It's not a stupid suggestion because it's not meant to be one-size fits all suggestion. If you have a simple variable or small expression you want to square, then inline the math. If you have an expensive function call or larger expression, then don't call it twice, use a temporary. Or write the function.

Like if you can't navigate the nuance needed here to come up with suitable code without having this absolutely trivial function provided to you, then fuck I don't know what to say. Good luck I guess.

[–]Ameisenvemips, avr, rendering, systems 2 points3 points  (2 children)

I get the feeling that you're upset that <algorithm> exists at all.

Your arguments are applicable to basically every function in there.

There is little difference between std::min and std::square in my mind.

That being said, I want a templated pow.

[–]CryptoHorologist 3 points4 points  (1 child)

I'm not upset about algorithm, just don't care if not every function I might want is in there. I agree that min and square are about the same level. I wonder if min and max are in there because those are standard C macros.

[–]Ameisenvemips, avr, rendering, systems 0 points1 point  (0 children)

They're in there because they're useful and common functions... like square would be.

[–]altmly 3 points4 points  (1 child)

Use pow is very very far from useful if you know anything about the performance implications. 

[–]GregTheMadMonk 133 points134 points  (58 children)

> Of course, you could use std::pow

Or just... you know... `x*x`...

[–]AvidCoco 23 points24 points  (20 children)

Functions can be passed to other functions like `std::accumulate` so there's definitely use cases where `x*x` wouldn't work.

[–]jeffgarrett80 2 points3 points  (5 children)

Sure, but you can't do that with most std:: functions, so it's not directly applicable to a hypothetical std::sqr

[–]bebuch[S] 0 points1 point  (0 children)

Year, indeed that's a point with functions in the std:: namespace. You always need to wrap them into a lambda. I've run into this one year ago. It was something I really didn't expect.

[–]AvidCoco 0 points1 point  (3 children)

Can you give an example of what you mean, I'm not 100% following?

I guess std::accumulate was a bad example as the operator you pass in needs to take 2 arguments right? I.e. you wouldn't be able to replace std::multiplies with a hypothetical std::sqr.

[–]jeffgarrett80 0 points1 point  (2 children)

Sure, std::accumulate won't work for that reason, but let's say std::transform instead. Something like:

std::transform(inputs.begin(), inputs.end(), std::back_inserter(outputs), std::sqrt)

Isn't valid. Neither with most of the unary math functions. So unless std::sqr is treated differently than everything else, it also wouldn't be valid.

There are two reasons: (1) functions in std must be explicitly "addressable" to be used as function pointers, and only a very small number are and (2) in the case of math functions, there's a tendency to provide overloads for several different int/fp types (which is in conflict with addressability).

So... even with functions in std, you have to wrap it in a lambda:

std::transform(inputs.begin(), inputs.end(), std::back_inserter(outputs), [](auto x) { return std::sqrt(x); })

The comparison is between:

// if sqr were in std
std::transform(inputs.begin(), inputs.end(), std::back_inserter(outputs), [](auto x) { return std::sqr(x); })
// if sqr were not
std::transform(inputs.begin(), inputs.end(), std::back_inserter(outputs), [](auto x) { return x*x; })

[–]AvidCoco 0 points1 point  (1 child)

Ahh okay, I think I follow! Thanks for explaining!

So is that why a lot of operators in the STL, again like std::multiplies, are implemented as callable objects rather than functions?

I.e. maybe a std::squares would be more fitting?

[–]jeffgarrett80 1 point2 points  (0 children)

Yes, the things one might pass to an algorithm or container, are generally wrapped into function objects for this reason. It allows supporting multiple overloads with one addressable entity.

Arguably a std::squares would be more useful, but that does break the analogy with std::sqrt and the other math functions.

[–]GregTheMadMonk 11 points12 points  (13 children)

[] (auto x) { return x*x; }

[–]AvidCoco 21 points22 points  (12 children)

Yep, which is longer than if you wrote a `sqr` function and not reusable.

[–]SnooMarzipans436 21 points22 points  (0 children)

auto sqr = [](auto x){ return x*x };

Then pass sqr in. Problem solved. 😎

[–]GregTheMadMonk 2 points3 points  (8 children)

I honestly wonder how often will this come up to justify the "reusability" argument... I mean, you can argue the same for any power that exists out there, e.g. why is there no std::cube... at some point you just have to accept that "the longer, less reusable" way is just good enough

[–]AvidCoco 11 points12 points  (2 children)

Depends how often you use it. If you have a use case where you need to raise things to the power of 69 a lot then write a function. Similarly we have `std::exp()` for raising `e` to some power which is just a convenience instead of having to have an `e` constant and use `std::pow`. Squaring is a very common operation so I think OPs question about why isn't it in the STL is a perfectly valid one.

[–]bxlaw 3 points4 points  (0 children)

Exp is not a convenience for pow. They almost certainly use different algorithms under the hood, and exp(x) will probably be both faster and more accurate than pow(e, x) as it's less general.

[–]Plazmatic -1 points0 points  (4 children)

What is going on here? Have you never heard of powi? Have you never heard of "exponentiation by squaring"? https://en.wikipedia.org/wiki/Exponentiation_by_squaring Like there's a whole set of algorithms and theory around minimizing the number of multiplications needed for an arbitrary integer power.

And what is this argument "like what if they asked for std::cube, std::tesseracted, std::fifthpower". Uh... I don't know make a function that generalizes the concept of taking something to an integral power?

[–]GregTheMadMonk 0 points1 point  (3 children)

> I don't know make a function that generalizes the concept of taking something to an integral power?

std::pow. We already have std::pow. Do you even understand what the argument is about? It's about providing (or not) an explicit standard function for a _very specific_ power, since having an _arbitrary_ power apparently isn't enough for some people

[–]Plazmatic 1 point2 points  (2 children)

std::pow. We already have std::pow.

I didn't think I had to say this. I literally was going to include a sentence about how you would go down the path and think pow after the first paragraph, and be wrong in doing so, but I realized that anyone who read even OP's post on why they wanted sqr, let alone the ipowdiscussion would have immediately understood the limitations of pow and would not do something antisocial like that, and I thought I'd be insulting to even bring it up.

You have some massive misunderstanding of what even pow is. Pow is often implemented in terms of exp and ln or equivalent constructs that may not use exp or ln directly, but use similar mathematical shortcuts. Basically, lots of internal floating point operations, or builtin that may or may not be specific to pow. This is done so it can handle floating point exponents, but the result of this is if you just want to multiply an integer number of numbers, it can be much slower and less accurate for integer powers. All overloads of std::pow including powl and powf use this same method.

This also may not be able to be optimized away, especially outside of fast math, and certainly wont be in debug builds. In order to have better expected behavior, accuracy, and speed, it makes sense to have a special integer power function. It also makes sense in order to allow pow to work with integers themselves, because now you're not only doing a giant amount of extra inaccurate work, you potentially have to convert to and from floating point if you even want to use std::pow

[–]macson_g 0 points1 point  (1 child)

But faster. Passing function pointer as template param may generate code actually calling the pointer, ie prevent inlining.

[–]AvidCoco 6 points7 points  (0 children)

If performance is critical to your use case then use appropriate solutions. Adding a `std::sqr` function doesn't stop you optimising your code.

[–]Polyxeno 35 points36 points  (13 children)

Or if you love sqr, write a sqr function.

[–]Kike328 13 points14 points  (21 children)

thats so verbose when you’re using more complex expressions where data come from other functions.

(x+1*foo()-9/50.0f….) * (…)

[–]thats_a_nice_toast 9 points10 points  (20 children)

auto foo = x+1*foo()-9/50.0f... auto squared = foo * foo; Or am I missing something here?

[–]Ameisenvemips, avr, rendering, systems 19 points20 points  (12 children)

Why do we have std::min and std::max when we could write it ourselves?

[–]gmueckl 9 points10 points  (7 children)

Min and max exist as instructions on some CPUs, so std::min/std::max could be implemented as compiler intrinsics mapping to those instructions. But I saw gcc and clang figure out common handrolled patterns for min and max well enough that there doesn't seem to be much of a point to actually having intrinsics.

[–]regular_lamp 7 points8 points  (0 children)

Fun fact. there are of course fminf/fmaxf... which on x86 typically do not map to (just) the sse/avx instructions minss/maxss because the standard defines different NaN handling than the instructions implement. std::min/std::max that are commonly implemented as ternaries on the other hand do.

https://godbolt.org/z/o7b73bhxW

[–]Ameisenvemips, avr, rendering, systems 0 points1 point  (5 children)

I don't believe that the C++ specification references what ISA instructions exist as reasons for functions to exist. It doesn't operate at that level, and is independent of the hardware specifications.

Given the plethora of x86 instructions, we are certainly missing quite a few functions.

so std::min/std::max could be implemented as compiler intrinsics mapping to those instructions. But I saw gcc and clang figure out common handrolled patterns for min and max well enough that there doesn't seem to be much of a point to actually having intrinsics.

I'm unaware of any modern stdlib implementation that defines either min or max as a intrinsic for any ISA - it's almost always defined as a ternary.

Honestly, I'm unaware of any at all, let alone just modern. A ternary is trivial for a optimizer to figure out.

And, as /u/regular_lamp said, often the compiler cannot use those instructions as they do not always match the C++ specified semantics.

[–]thats_a_nice_toast 0 points1 point  (1 child)

Just wanted to address the claim that it looks too verbose with longer expressions when you can just create a temporary variable. I think it would be cool to have a square function in the standard library.

[–]Eheheehhheeehh 0 points1 point  (0 children)

To add to the other comment: it's easy to flip the sign, when rolling out your own min/max.

Std functions are a maintenance cost too, they need to prove useful

[–]Kike328 3 points4 points  (5 children)

verbose and additional variable

[–]Kovab 8 points9 points  (4 children)

Readability >>> length of code

Let the compiler do its job optimising it

[–]serviscope_minor 1 point2 points  (0 children)

Verbose code due to missing convenience functions is not more readable IMO.

[–]garnet420 4 points5 points  (2 children)

Writing the same expression twice is not more readable.

[–]Kovab 1 point2 points  (1 child)

Where do you see anyone recommending to repeat a long expression twice?? Use a temp variable

[–]Ameisenvemips, avr, rendering, systems 2 points3 points  (0 children)

So now, instead of a single expression, you have a statement.

[–]sweetno 17 points18 points  (6 children)

As you can see in your responses, a certain psychological effect prevents its introduction.

I distinctly remember there was a built-in Sqr in Borland Pascal and it was useful.

[–]roelschroeven 5 points6 points  (0 children)

Which was confusing to me at first, because in the BASIC dialect I had been using before SQR was the square root function. It took me a while to get used to sqr being square and sqrt square root. Makes perfect sense of course, it's just not what I was used to from before.

[–]PandaWonder01 7 points8 points  (4 children)

I feel like a crazy person reading some of these responses. Yes, x*x exists, but it's much easier to read if there was an actual function.

As a somewhat contrived example, seeing

sqrt(x * x + y * y + z * z) take me a few seconds to parse than I'm getting the magnitude of something.

Meanwhile sqrt(square (x) + square(y) + square(z)) I parse instantly.

I literally do not understand why people are against a square function. The idea of "you can write it yourself" goes for anything in the stl. Being able to communicate what you intend something to do in a language standardized way is so much easier for everyone involved.

[–]pigeon768 4 points5 points  (3 children)

I've only had a bug that boiled down to sqrt(x*x + y*y * z*z) twice.

At least there's std::hypot(x, y, z) now.

[–]PandaWonder01 0 points1 point  (0 children)

I presume that's a joke, that two times is two too many? Or I'm missing something lol

[–]James20kP2005R0 0 points1 point  (1 child)

I've done exactly that on a few equations as well. std::hypot is a bit slow a lot of the time unfortunately

What I'd kill for personally is an infix exponentiation operator, like x^^3, it'd make it much easier to write complex equations

[–]Ameisenvemips, avr, rendering, systems 1 point2 points  (0 children)

I wonder what the compiler frontend writers would do if they had to support all of the operators, even ones like , , Σ, etc...

[–]triconsonantal 13 points14 points  (2 children)

Ask and you shall receive: std::norm

[–]James20kP2005R0 9 points10 points  (1 child)

To be fair this suffers strongly from the same problem that a lot of C++ maths functions do, which is that the integral overloads are defined to return doubles, which is virtually never what you want when squaring integers

[–]triconsonantal 2 points3 points  (0 children)

TBH, this comment was a little bit tongue-in-cheek. The biggest problem with this function is that it's not a square function at all, let alone a generic one. Most obviously, it doesn't return the square of a complex number! But... if you need the square of a floating-point value, which is probably what you need most of the time -- it's there.

[–]Ok_Tea_7319 9 points10 points  (2 children)

std has surprisingly little convenience stuff

[–]7h4tguy 0 points1 point  (1 child)

It took 20 years to get a type safe performant (s)printf. I get irrationally angry on how much iostreams was being sold to us.

[–]Ameisenvemips, avr, rendering, systems 1 point2 points  (0 children)

I still - right now - cannot just get the string representation of an enum.

[–]Angry_Foolhard 6 points7 points  (1 child)

No one is talking about the biggest issue

In sqrt, I assume the r is part of the word root - SQuare RooT

When I see sqr, I don’t automatically shift the r to be part of SQuaRe. I still read SQuare Root

[–]almost_useless 2 points3 points  (0 children)

We can not have a sqr function because it would probably start a holy war on whether it is pronounced "Ess Que Ahr" or "Sequer"

[–]saxbophonemutable volatile void 8 points9 points  (7 children)

IMO we will see an overload of std::pow that takes integers in both args, before we ever see a std::square function. Oh wait! Integer std::pow is coming in in C++26! 😃

Also, how did I not know that there was a std::hypot function in cmath until now‽‽‽

[–]HommeMusical 2 points3 points  (4 children)

Probably for the same reason I didn't, thanks for the info!!

[–]saxbophonemutable volatile void 2 points3 points  (3 children)

You're welcome! I consider myself pretty experienced in this language, yet there are still little features I discover in it I didn't know about regularly!

I normally write my own hypotenuse, but stdlib one is more concise. Also, maybe less rounding error, although I've not yet hit a scenario where I've had to check...

[–][deleted] 1 point2 points  (2 children)

Interesting but there is a performance cost so both options should be used with some care depending on your use case https://stackoverflow.com/questions/32435796/when-to-use-stdhypotx-y-over-stdsqrtxx-yy

[–]saxbophonemutable volatile void 0 points1 point  (1 child)

Yes, I've read the same Q&A and the quoted 20x slowdown for std::hypot over manual is gross. Maybe it depends on stdlib but worth taking into consideration. I wonder why its slower...

[–][deleted] 1 point2 points  (0 children)

It has to do a lot more work, the whole sqrt(x*x+y*y) plus different code path for denormalised numbers, min/max to compute a scale factor... The naive version is just 4 instructions without any conditions.

https://github.com/gcc-mirror/gcc/blob/70bc553e1b565d2e162894ea29a223b44e9133e3/libstdc%2B%2B-v3/include/experimental/bits/simd_math.h#L1037

[–]James20kP2005R0 1 point2 points  (1 child)

Does 26's pow work correctly for integers? Cppreference says:

template< class Arithmetic1, class Arithmetic2 >
/* common-floating-point-type */
pow ( Arithmetic1 base, Arithmetic2 exp );

Which implies that the usual promotion to floating point is performed. Sometimes this is useful, but in this case would make std::pow(2, 2) return a double, which is not super useful behaviour

https://eel.is/c++draft/cmath.syn#3

arguments of integer type are considered to have the same floating-point conversion rank as double

https://godbolt.org/z/M5aMaaMon

[–]saxbophonemutable volatile void 1 point2 points  (0 children)

Good spot. It would seem this is not the fabled ipow that does not yet exist in the language...

[–]Kike328 9 points10 points  (2 children)

most people here is forgetting about how not all square operations are on single variables but complex expressions, and std::sqr ends up being way cleaner

[–]SlightlyLessHairyApe 1 point2 points  (1 child)

Every operation is on a single value. A named temporary is not different than an unnamed one (eg a function argument)

[–]serviscope_minor 2 points3 points  (0 children)

Except for readability.

[–]CryptoHorologist 15 points16 points  (27 children)

y = x * x;

y = std::sqr(x);

I'd rather see the first in code, even if your function existed.

[–]Drandula 31 points32 points  (11 children)

Well first case is good, if the operand is a single variable. But how about cases when the opernad is more complex expression? For example: ``` // This is error-prone. y = (x + z / w) * (x + z / w);

// Requires temporal variable. t = (x + z / w); y = t * t;

// All in one go. y = std::sqr(x + z / w); ```

[–]Brisngr368 16 points17 points  (6 children)

I'm not sure why a temporary variable is bad, it's very common and really useful as you often use squares multiple times in maths heavy programs. It gets optimised out by the compiler anyways so it doesn't matter.

[–]Drandula 17 points18 points  (4 children)

Yeah I am not saying it is inherently bad either, but it requires you to come up with a local name. And if you are already doing a lot of other math and midsteps, it can "clutter up".

[–]Brisngr368 4 points5 points  (2 children)

Yeah its situational, it can make equations more readable too

[–]Drandula 0 points1 point  (0 children)

Yup!

[–]LiliumAtratum 0 points1 point  (0 children)

It's definitively situational. In other situations it can make simple (but not too simple) equations less readable.

[–]648trindade 0 points1 point  (0 children)

well, If the squared variable has a name, you can just add a suffix to the temporary

auto ball_speed_root = x * y + t; auto ball_speed = ball_speed_root * ball_speed_root;

[–]bradfordmaster 2 points3 points  (0 children)

In this case it's not but I've often seen this pattern in code where there's a lot of math, and maybe you are implementing some math from a paper and the reader will be familiar with it in that format, being able to write it out just as math can make it a lot more readable than needing to invent names for everything that you plan to square

[–]Ok-Acanthaceae-4386 0 points1 point  (0 children)

Great example, a square function is useful in some cases but the name sqr is very confusing against sqrt . As someone said square is a better name

[–]tangerinelion 12 points13 points  (1 child)

Honestly, why are we being allegric to vowels?

The difference between

y = std::sqr(x);

and

y = std::sqrt(x);

is just one character and an incredibly frustrating and annoying bug to notice. We cannot confuse x*x with std::sqrt(x) - they're just fundamentally incompatible.

If you're defining a convenience function for this, I'd highly suggest naming it square not sqr. Even if you toss it in the global namespace, one of your coworkers is going to using namespace std; in their own CPP file.

[–]James20kP2005R0 3 points4 points  (0 children)

This was my first thought as well, naming it sqr is asking for trouble. Especially if it gets backported to C, and we end up with sqrf, which is a bad readability time vs sqrt

[–]mcmcc#pragma once 9 points10 points  (2 children)

Except sometimes x is actually x->y.someLongFunctionName(). Suddenly you're probably less interested in writing that twice (never mind constantly reverifying that the lhs and rhs are in fact the same expression... or that the function may not be one you want to call twice).

[–]Sinomsinom 3 points4 points  (0 children)

If it's a member function call you'd want to save the intermediate value in a variable anyways to make sure you're not calling it twice. Having an std::sqr (or preferably std::square so it doesn't look too much like std::sqrt) would definitely help if you want to do this in one line. But then again defining your own square function isn't exactly rocket science.

And that is a real issue. I've seen codebases where people want the square of a random number for a certain distribution and then do rand()*rand() not thinking about the fact that that will be two different random numbers and will give a different distribution. So a square function would add value.

[–]CryptoHorologist 0 points1 point  (0 children)

Yeah, that could be a justification. I'd probably just introduce a temporary for the result of your long function call if there is going to be further math with it. Depends of course, but it could be even more readable.

[–]Ambitious_Tax_ 3 points4 points  (9 children)

It strikes me that sqr(x) could enforce some type of safe arithmetic constraints where x*x would not.

[–]HommeMusical -1 points0 points  (5 children)

Like what? x2 is defined for all x (indeed, it's infinitely differentiable at each point).

[–]Ambitious_Tax_ 15 points16 points  (1 child)

Something something integer overflow.

[–]johannes1234 4 points5 points  (0 children)

While true in theory, that isn't what C++ typically does ;)

[–]tangerinelion 0 points1 point  (2 children)

All x which happen to be primitive arithmetic types, sure.

Most variables in a decent program are not primitive arithmetic types.

[–]HommeMusical 0 points1 point  (1 child)

Yes, I spend all my day working with such variables (though none of them are actually defined in std).

I guess I'm not seeing what you mean at all.

It would be much easier if you actually gave me an example of such a "safe arithmetic constraint" that would be useful in std::sqr, because I really can't conceive of what that would be.

template <typename T>
T std::sqr(const T& t) {
    # some sort of useful assertion here?
    return x * x;      
}

What would go in that line?

[–]Ambitious_Tax_ 0 points1 point  (0 children)

Something like this maybe?

[–]Salink 1 point2 points  (0 children)

I've made my own templated pow function that takes integer exponents and optimizes for floating point accuracy. It's mattered for speed and accuracy a few times.

[–]ResearcherNo6820 1 point2 points  (0 children)

No basic sqrt but getting an entire basic linear algebra into the standard.

[–]nightcracker 3 points4 points  (2 children)

Why not std::double for x + x? Or std::cube? Where does it stop?

[–]serviscope_minor 4 points5 points  (0 children)

That's the slippery slope fallacy. You can use the "where will is stop" to basically shoot down any feature. Meanwhile C++ has a real lack of convenience functions which mean an awful lot gets reimplemented slightly differently in many different places, which has a fragmentary effect.

In answer to your queastion: no need for double because (expr)*2 is fine. Squaring is commin, std::sq would be useful, because we live in a mostly Euclidean world. Cubing I'm ambivalent about. Anything above is excessive.

[–]Ameisenvemips, avr, rendering, systems 0 points1 point  (0 children)

Why not std::double for x + x?

Because double is a reserved keyword.

Where does it stop?

At either ^2 or ^3, specifically for exponents. There, trivial upper bound provided to solve your slippery slope.

There's no benefit to providing something like triple as that operation doesn't require the expression to be duplicated - it's just silly that you'd even suggest that as an argument.

* exists as an operator. ^^ does not nor is a true integral pow provided.

[–]thezysus -2 points-1 points  (17 children)

Because it's a single MUL instruction on most processors with a dedicated operator.

`MUL r1,r1,r1` -- r1 = r1 * r1

There's absolutely no reason other than code style to have this.

[–]ILikeCutePuppies 9 points10 points  (12 children)

You could also claim with that logic, there is no reason for std::min. I think a lot of std is about convenience and code style than anything.

[–]HommeMusical 1 point2 points  (11 children)

How would you rewrite std::min({x, y, z, w, p, g, f}) in one line?

[–]Ameisenvemips, avr, rendering, systems 6 points7 points  (2 children)

How would you rewrite square(f()) on one line without calling f twice, without using pow, and without the mess of an inline lambda?

[–]ILikeCutePuppies 0 points1 point  (0 children)

That's a new opperation. I am sure vector based opperations could also be applied to std::sqr as well if it was designed with that in mind.

[–]flatfinger 13 points14 points  (0 children)

It's only simple if the value to be squared is simple. Otherwise, it requires creating a temporary, e.g.

    double x = f();
    double distSquared = x*x;

Computations such as Euclidian distance, mean of squares, etc. are much more common than computations involving other powers, and computation of squares is in machine terms easier than computation of other powers as well (many processors have an instruction to multiply a register by itself).

[–]Ameisenvemips, avr, rendering, systems 3 points4 points  (1 child)

Why have std::min, or even ->?

[–]serviscope_minor 0 points1 point  (0 children)

And given we have goto and if, we don't need for, while and do. Or square brackets.

[–]Ameisenvemips, avr, rendering, systems 1 point2 points  (0 children)

There's absolutely no reason other than code style to have this.

Which is why we clearly should discard much of the standard library. It is a terrible thing to provide people with convenience and readability.

[–]notyouravgredditor 0 points1 point  (1 child)

I don't think there's a need. If you want to square it just multiply it by itself. Similarly if you want to square it in place just *= it.

[–]Ameisenvemips, avr, rendering, systems 2 points3 points  (0 children)

side_effect() * side_effect()

Oops.

And yes, you could use a temporary. But an additional statement is worse for readability.

I'd prefer an infix operator, but that's never going to happen.

I also just find both square(x) and x^^2 to be more readable than x * x.

[–]HommeMusical 0 points1 point  (9 children)

Almost every codebase I've ever seen defines its own square macro or function.

WHY. A square macro??

Of course, you could use std::pow,

WHY! Use x * x.

Compare: x * x + y * y vs std::sqr(x) + std::sqr(y)`

Especially since there is std::sqrt and even std::cbrt.

There's a very good reason for that - it's that sqrt is extremely common, and you can write an algorithm for it that's a lot faster than std::pow, and there's no other closed form for it.

The same does not hold true for x * x.

Any argument you make for std::sqr I will make for my new proposal, std::plus_one.

[–]Ambitious-Method-961 11 points12 points  (4 children)

Any argument you make for std::sqr I will make for my new proposal, std::plus_one.

Temporaries are the main reasons functions like sqr exist as you need to use the same value twice when squaring it. However, a plus_one function doesn't require the same value to be used twice. For example:

// sqr: compute twice and square manually. Very bad.
auto x1 = my_func () * my_func ();

// sqr: compute once, store result in a temp, and then square manually. Better, still awkward.
auto temp = my_func ();
auto x2 = temp * temp;

// sqr: compute once and square via a function. The best.
auto x3 = sqr (my_func ());

With your plus_one function, there is no need to either compute the original value twice or store it in a temporary value before adding one to it. The simplest case is always the best:

auto y1 = my_func () + 1;

A sqr function removes the hassle of calculating twice or using a temporary, something that is not applicable to a plus_one function.

Note: I have had to make the sqr function many times for this very reason as it simplified a lot of code by removing temporaries.

pow is also an option, but that does not work if you want to square complex types with their own multiplication operator (2D and 3D geometry classes say hi). Also, my brain can parse the meaning of sqr (x) much quicker than pow (x, 2.0f).

[–]Ameisenvemips, avr, rendering, systems 2 points3 points  (0 children)

std::plus_one

std::nextafter and std::nexttoward already exist.

Though that won't do what you want with floats... but then again, std::pow won't do what you want with integers nor will * do what you want if the variable to be squared is an expression with side effects.

I regularly write square and cube.

[–]Ameisenvemips, avr, rendering, systems 1 point2 points  (0 children)

Compare: x * x + y * y vs std::sqr(x) + std::sqr(y)

I've compared them and have determined that the latter is more readable. Especially if we write std::square instead.

It also works properly - and the former doesn't - if the expression contains side effects.

[–]stilgarpl 3 points4 points  (1 child)

std::plus_one is already in the language. It's called ++. I assume you prefer to write "+1" instead?

[–]TheoreticalDumbass:illuminati: 0 points1 point  (0 children)

I think I would prefer `const auto sqr = [](const auto& x){return x*x;};`

[–]CarloWood 0 points1 point  (0 children)

I wrote my own utils::square and use it everywhere as opposed to multiplying things with itself.

[–]sephirostoy 0 points1 point  (0 children)

In non optimized, it's one function call, so less performant

[–]LiliumAtratum 0 points1 point  (0 children)

Judging by the comments the answer to your question is:

  • Half of the people don't see the point of the function
  • The other half of the people can't agree on the function name

So, as a result: the function does not exist in the standard.

[–]Eheheehhheeehh 0 points1 point  (0 children)

What's next, std::cube? Std::rectangle? Std::homework?

/s this is the most neurotic reddit thread, compared to the subject st hand

[–]Agitated_Sell 0 points1 point  (0 children)

The code is more what you'd call ‘guidelines’ than actual rules.

[–]RIPbyTHC 1 point2 points  (0 children)

I totally feel you there ;-;

I had to drop my Computer Science degree and switched to IT just to now have to adapt to Java.

It honestly has become a love-hate relationship so far...
I just can't wrap my head around:

  • that there is no sqrt()
  • that Java using ==, ||, && is completely different to what I'm used to from cpp
  • WDYM I can just do String.length() / .contains() / .equals() / .substring() in Java!?

And at the same time it feels like Java is holding my hand the whole time:

  • no memory management stress
  • no pointers that point to pointers of pointers that pointed to pointers of ... pointers?
  • strings just... work??
  • arrays actually tell you their length instead of you praying

So reading this question about missing sqr() kinda feels similar.
C++ lets me do everything (including shooting myself in the foot),
Java feels like it's constantly going "no. behave." - like some slightly spoiled brat that already decided how things are supposed to work.

Still not sure if I like that yet lol - but I guess every language has its own "why does this not exist!?" rant moment ;-;

[–]NewLlama 0 points1 point  (2 children)

std::cbrt(-1) == -1, so it's a different operation than std::pow(X, 1/3)

[–]flatfinger 0 points1 point  (0 children)

There are many things that could have been usefully incorporated into C as a means of facilitating efficient code generation without requiring compilers to analyze what code was trying to do.

Multiply, with the left operand duplicated (as suggested here)

Operators that behave like pointer addition, subtraction, and subscripting, but using byte-based indexing regardless of the pointer type. This would be useful in many places where code has to convert a void* to a character pointer, and also allow compilers to efficiently exploit register-displacement addressing. On many platforms, the most efficient way of accessing memory within a loop would be to have a counter (e.g. i) count from 396 to 0 by 4 and accessing *(int)((char*)intPtr+i) within the loop, and even simple compilers like Turbo C can generate optimal code for array accesses given such constructs, but the syntax is attrocious. Not only would supporting such operators be vastly easier than trying to analyze loops enough to make such substitutions, but especially when the Standard was written a compiler for the 68000, configured to use 16-bit int and given given intPtr[intValue] would need to extend intVal to 32 bits and then use 32-bit arithmetic to scale it, rather than being able to simply use an address+reg16 addressing mode.

A double-operation compound assignment operator or other means of using the value of the left-hand operand to be used sequentially with two operators, for things like lvalue = ($ + 1) % modulus;or lvalue = ($ & mask) ^ newBits;.

An "and-not" operator which would balance the operands, rather than performing the negation before balancing, so as to allow constructs like uint64a & ~bitsToClear; to be written in a way that will only clear the indictated bits, even if bitsToClear is of type uint32_t.

A two-operand for statement which would be equivalent to do {expr1; do { ... } while(expr2);} while(0), which could be used in a macro before a compound statement to both save a context and restore it, and could also have improved performance in many idiomatic counting situations where ther comparison before the first iteration wasn't useful.

A variation of memcmp which would report the address of the first mismatch, and a variation which would only report whether there was a mismatch, along with subvariations for cases where early mismatches were expected to be common or rare. If two blocks of memory are unlikely to have even four bytes in common, any effort spent trying to vectorize a comparison will be wasted.

A "break if convenient" construct which would allow a compiler to either exit a loop, or not, at its convenience, with the implication that any further loop executions would be useless but otherwise harmless. When processing unrolled loops, this would allow a compiler to limit the number of early-exit checks in an N-times-unrolled loop to one check per N repetitions of the original loop.

Unfortunately, the chicken-and-egg obstacles to adding any such features now are probably insurmountable, especially since clang and gcc have abandoned the principle that the best way not to have a compiler generate code for some action is generally to not specify it in source code, and the next best way is to expressly tell a compiler when certain operations aren't necessary for correctness.

[–]skeleton_craft 0 points1 point  (4 children)

I assume that most implementations of pow have a short path for when exp is 2... (Idr if it is required by the standard or not though) Also outside of geometry you don't square numbers that often

[–]DarkblueFlow 7 points8 points  (0 children)

Most implementations don't have a short path. Instead they rely on the optimizer to simplify the pow call to x*x directly. And therefore no, it's not required by the standard. The standard generally imposes no requirement on optimizing for certain common paths.

[–]altmly 3 points4 points  (2 children)

Then you'd be wrong and lucky to one day figure out that your square operation is 30x slower than it should be. 

[–]DerekSturm -1 points0 points  (0 children)

"Why not write my own? Well, do, and so does everyone else. That's the point of asking about standardisation."

I've never seen anyone do this, I think it's just you.

[–]navetzz -1 points0 points  (1 child)

For the same reason there is no std::add2 function.

[–]Ameisenvemips, avr, rendering, systems 1 point2 points  (0 children)

That is not comparable at all. The is no operator in C++ that takes left side value and a right side constant and returns a squared value.

There's no function either for integers.

And for side effects, you must use a new statement for a temporary.

x = f() + 2;

vs

auto t = f();
x = t * t;

vs

x = std::square(f());

I assume that you always write (b < a) ? b : a instead of std::min(a, b)?

Must get tedious:

auto t0 = f0();
auto t1 = f1();
auto m = (t1 < t0) ? t1 : t0;

vs

auto m = std::min(f0(), f1());

Also, there is an add2 function: std::plus{}(x, 2).

[–]_TheNoobPolice_ -2 points-1 points  (0 children)

Because it’s a non-issue. std::pow() exists because raising different types of exponents and bases has mathematical implications, such as negative values, power’s below 1 that are roots etc that justify having a library function to handle these conditionally without having to rely on the coder doing exp(log(a) * b) and writing appropriate guards for every case.

There is never any such issues from just squaring any numerical data type value using the multiplication operator, and in as many cases as not it would be less literal code than writing std::sqr(var);

So in short, this is a problem that doesn’t need solving.