What practically annoys you on a regular basis in programming languages?

Recommended Posts

25 minutes ago, Oberon_Command said:

What's unintuitive or odd about this? It's certainly not always convenient, but the idea that comparison operators are binary (and more complex conditions are created by composing them) is a simple and clear one.

What's non-intuitive.. When comparison operators are interpreted from this (5 < b < 10) into ((5 < b) < 10), which I would argue is useless (comparing a boolean with 10), rather than doing a chained expansion into the more useful (5 < b && b < 10).

EDIT: Just found this recent proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0893r0.html

25 minutes ago, Oberon_Command said:

It seems intuitive enough if you keep in mind that char* as "pointer to string" rather than "string ﻿value." I would further argue that this is the correct way to think of a char* an﻿d "a == b" in your example is the ﻿behavior that I﻿ would ex﻿pect. ﻿﻿

I can agree with that. How about, assuming a strongly typed typedef mechanism is available, and if I'd typedef char* as cstring. As the pointer is now "hidden" from the programmer, would it be more acceptable to overload == on that cstring type?

Edited by Kaetemi

Share on other sites
7 hours ago, Kaetemi said:

if (5 < x < 10) { }

Clearly you're using the wrong language 😛

Quote

Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).

Share on other sites
5 hours ago, Oberon_Command said:

I'd be fine with just automatically calling operator== on each member as the default. We already get that with the implicit copy constructor/assignment operators. If the default doesn't do what I want, I'll override it, but most classes I work with are just doing that, anyway. It's the most usual case and therefore should be the default and automatic one.

My assumption is that the standards committee, being highly concerned with the implementation of the standard libraries, often encounters cases where this is not the default situation. It seems to me that, in general, there is a distinct trend of the standards committee prioritizing library authors when adding new features and rules.

Or perhaps this is an aspect of the "zero cost abstractions" philosophy and the committee doesn't want to force (what I consider) the reasonable default on everyone on the grounds that it would be a default with potential runtime costs. But... we already have that, with copy constructors... And now I'm just speculating.

My expectation here as a C++ programmer would be deep equality, because that's how the standard library types generally behave and how the vast majority of user types I have encountered in production code behave. If I wanted identity rather than equality, I would compare the pointers or similar - eg. handles, in cases where my data is double-buffered or relocatable. If you want to do something else in your own idiom, that's fine, that's why we have operator overloading, but in C++ I'm always going to expect a deep comparison and you should specifically tell me when the type is doing something different.

IMO operator overloading should be reserved for non-default cases and should not be required for holding the compiler's hand through the default ones.

Unless I misunderstand you're getting exactly that, plus auto-generated ordering: https://en.cppreference.com/w/cpp/language/default_comparisons

Share on other sites
2 hours ago, Eternal said:

Unless I misunderstand you're getting exactly that, plus auto-generated ordering: https://en.cppreference.com/w/cpp/language/default_comparisons

To be clear, what I'm actually looking for is to be able to do this:

struct Point {
int x;
int y;
};

Point a = get_point_a();
Point b = get_point_b();
if (a == b) {
// ...
}

Which currently I cannot, because operator== is not defined automatically. I want the compiler, for simple types, generate an implicit operator== just as it does an implicit copy constructor, without my having to overload anything. Furthermore, my argument is that the reasonable default is member-by-member comparisons.

8 hours ago, Kaetemi said:

I can agree with that. How about, assuming a strongly typed typedef mechanism is available, and if I'd typedef char* as cstring. As the pointer is now "hidden" from the programmer, would it be more acceptable to overload == on that cstring type?﻿﻿

A strong typedef doesn't actually change the type, though. It would just disallow implicit conversions with the type it aliases. So no, I wouldn't want a deep compare operator== in that case, because the actual type of cstring is still a pointer type and it still behaves like one in all other respects. "C-string" means "pointer to string." If you wanted to write a wrapper type that did deep equality, that would be fine with me, but then I'd say it should be called something else, like "weak_string" or "string_view" (which we have in the standard!).

8 hours ago, Kaetemi said:

When comparison operators are interpreted from this (5 < b < 10) into ((5 < b) < 10), which I would argue is useless (comparing a boolean with 10), rather than doing a chained expansion into the more useful (5 < b && b < 10).﻿

I doubt that's really going away any time soon. Booleans being implicitly castable to integers is probably necessary for C compatibility. I suspect there exists at least one "load-bearing bug" that depends on this behavior and changing it would break somebody's code.

Share on other sites
1 hour ago, Oberon_Command said:

To be clear, what I'm actually looking for is to be able to do this:


struct Point {
int x;
int y;
};

Point a = get_point_a();
Point b = get_point_b();
if (a == b) {
// ...
}

Which currently I cannot, because operator== is not defined automatically. I want the compiler, for simple types, generate an implicit operator== just as it does an implicit copy constructor, without my having to overload anything. Furthermore, my argument is that the reasonable default is member-by-member comparisons.

That's fair, and I don't know why implicit definition of operator== didn't make it, it was proposed at some point. I wouldn't be too surprised if it was just lower priority and will appear in C++23.

Create an account

Register a new account

• 12
• 19
• 15
• 15
• 10
×

Important Information

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!