Hacker News new | ask | show | jobs
by nj5rq 734 days ago
> why C++ is unsafe is that it's full of these unnecessary footguns

I don't see the "footgun". C and C++ allow you to perform divisions by integers. If you don't specify the decimals, it understands that they are integers. It's how it's meant to be. In my opinion, calling that a "footgun" is like saying using single quotes for characters is a "footgun" because someone could interpret them as strings. That's just not understanding the language.

2 comments

"just read the docs" is a fully general counter argument that can be used to justify arbitrary bad design decisions

I think Python 3 did the right thing by having 1/3 equal 0.333 (a float) rather than 0. It's more intuitive for the / operator to always do standard division and when you want integer division then you use the // operator instead. It's more consistent than having / return a completely different result depending on whether one of the operand happens to be 3 instead of 3.0

Who said that "standard division" is floating point division? Something which is inherently full of surprises, to the point that most programmers can't even explain the mechanism in detail?

> It's more consistent than having / return a completely different result depending on whether one of the operand happens to be 3 instead of 3.0

I'd argue that you should be able to learn a few relatively simple rules that are baked into the language, and which don't change. That's not much to ask considering the value you get out of it.

On the other end of the spectrum, you have lots of people vigorously defending their manually overloaded arithmetic operators, acting on their custom types. And to have class methods overloaded statically (depending on argument types) and dynamically (virtual dispatch). I'm assuming you're not part of that group?

Not saying that it isn't a footgun, though. My recommendation is to turn on warnings and you should be able to catch most of mistakes early.

Are you saying that it is intuitive that 4/2 should return a floating point number? Or the type of the result should depend on the value?

I would expect that no C or C++ programmer would find it intuitive

> I would expect that no C or C++ programmer would find it intuitive

My guess is that if instead C and C++ had two operators here you'd find C and C++ programmers fiercely defending this reality as the only correct choice.

The tribalism particularly in C++ is very strong. There are a handful of accepted topics for disparagement, such as the std::vector<bool> specialisation but outside that any questioning of orthodoxy is not well tolerated.

Aside from the flame-baity strawman, I'm not sure for which behaviour you are exactly arguing for.
There are several attractive options, any of them eliminates this kind of bug

1. Giving the integer and floating point division operations different operators. If we designate // as specifically the integer division operation then this bug never arises.

2. Don't have untyped constants. If the old constant had been a floating point type, the erroneous change jumps out because we're obliged to write that we now want an integer type. Unfortunately the pre-processor is just text mangling, so this constant had no type as far as C is concerned. Odin is uncommon in modern languages for having untyped constants, Ginger Bill can probably explain why he thought that's a good idea but I can't defend it.

3. Forbid coercion/ promotion of numeric types (perhaps as part of forbidding silent type conversions in general) so now the original expression won't compile anyway.

> I don't see the "footgun".

    a / b
"Never" means "integer division" in regular math, so programming languages overloading it to sometimes mean integer division is a common suprise to newbies - especially when it's based on the types of `a` and `b`, which might not be determinable merely from reading the current file. Also, it's not equivalent to:

    a\b ≡ ⌊a/b⌋
As you might expect ( https://mathworld.wolfram.com/IntegerDivision.html ), but instead some round-to-zero nonsense that makes most uses of it on signed integers a bug IME. Some languages give integer division it's own syntax... others overload `a / b` to also mean path concatination.

And while it's not on my top 100 list of C or C++ footguns, it is one of those things that occasionally helps lead to a facepalm-inducing moment when even professionals have a brain fart and fail to consider it's overloaded behavior... or misremember the type of `a` or `b`... or change the type of `a` or `b`.

> That's just not understanding the language.

Learning the footguns and how to avoid them is an important part of understanding any language. That doesn't mean they aren't footguns, just that they can be (partially) ameliorated.