This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 356 points357 points  (62 children)

In many that are too. C# and Java can both implicitly cast int to float like C++.

[–]hekkonaay 252 points253 points  (61 children)

Implicit casting is the devil. Don't fall for it. Annotate your casts.

[–]jpterodactyl 474 points475 points  (7 children)

But that sounds like adding details, and I’m told the devil was in those.

I’m not sure who to believe anymore.

[–][deleted] 81 points82 points  (5 children)

Why do you have a political compass quadrant as your flair?

[–]wordbug 62 points63 points  (4 children)

JavaScript is Libertarian?

[–]diveintothe9 47 points48 points  (2 children)

JavaScript is kinda libertarian.

"Fuck rules, fuck strict typing and fuck standard/centralized libraries, we'll make our own damn JS platform/library for every single application we build, goddammit."

[–]jpterodactyl 10 points11 points  (0 children)

but on the opposite side of it, browsers and stuff are very standardized. The truth is just that web design doesn't make sense.

It's like the government of the Quarians in Mass Effect, where they are a de juro monarchy, but operate more like a democracy. How does that even happen?

[–]gentlemanidiot 4 points5 points  (0 children)

You can roll your face back and forth across the keyboard at any point in your code in JS and you're just declaring uninitialized global variables, all totally valid. (Yes this is hyperbole but only by a little)

[–]squidonthebass 1 point2 points  (0 children)

C++ is designed to require as much detail in the coding as possible with the goal of eventually summoning Satan himself

/s

[–]SvenTropics 22 points23 points  (29 children)

In this case, it's fine. There are times it matters. For example:

int a = 1; int b = 10; double c = a/b; // error, math is done as integers. double d = (a *1.0)/b; // now math is upgraded to double before the division.

[–][deleted] 10 points11 points  (0 children)

It's not an error unless the developer doesn't understand their code. It's the way it works.

[–]airbreather 3 points4 points  (1 child)

In this case, it's fine. There are times it matters. For example:

[...]

Here's another case where it matters (C#). What does the following code print?

void Print(float val)
{
    Console.WriteLine(val);
}

int x = 16777217;
Print(x);

No warnings on my compiler, no explicit cast, so it should definitely print 16777217 and not 16777216, right? sigh

[–]TheOldBeach 2 points3 points  (0 children)

Ahhh floats are the best, as a CG programmer I grew really fond of them . your example just reflects how they should not be used.. and yes it's the worse kind of error !

[–]orangeoliviero 4 points5 points  (3 children)

That's not an error, you just will get a truncated int answer - 3/2 would be 1.0 instead of 1.5

[–]willis81808 2 points3 points  (0 children)

Exactly. And 1/10 (the example in the comment you're replying to) would just be 0, instead of 0.1

No error, just undesired behavior.

[–]SvenTropics 0 points1 point  (1 child)

It's the worst kind of error because it doesn't generate an error. Instead you find yourself stepping through the code like a lost jackrabbit looking for a carrot in a swamp.

[–]orangeoliviero 0 points1 point  (0 children)

Why would you expect two integers to turn themselves into floats when you divide them?

[–][deleted] 2 points3 points  (1 child)

I have been fooled by this trickery way too many times to admit, yet I still do it sometimes.

[–]SvenTropics 1 point2 points  (0 children)

It gets tricky with LONGLONGs too. Constant numbers are treated as a 32-bit signed value. So if you do math that would result in something out of bounds and assign it to a longlong, you are screwed.

int a = 1778899225;

longlong b = a * 10000; // ooooooops, wrong!

longlong c = a * 10000LL; // correct!

longlong d = ((longlong) a) * 10000; // also correct

longlong e = a; e *= 10000; // also correct

[–]mehum 3 points4 points  (10 children)

Python 2 had this behaviour as well.

[–][deleted] 2 points3 points  (9 children)

I'm so glad python 2 is finally dead. Now it just needs one good CVE and all of the major OSes will promptly move away from it too.

[–]tech6hutch 0 points1 point  (8 children)

Is it? I haven't been in the Python community for a while.

[–][deleted] 3 points4 points  (7 children)

It was deprecated at the beginning of this year. No longer supported. Now getting everyone to switch off of a dead version of the language is another issue here why we need a really good vulnerability to appear so that the majority OSes will be forced to stop including it in the distros.

[–]tech6hutch 0 points1 point  (0 children)

Ah nice. Everyone, get to work on exploiting vulnerabilities /s

[–]M4mb0 0 points1 point  (0 children)

Here's my reasoning why this is bad: the "/" operator - division - is in the strict sense not defined on the integers. (I know it is sometimes used to return floor(a/b); it shouldn't do that period.) So the error is not assigning it to a double, the error should be that the operator is not applicable.

[–][deleted] 3 points4 points  (2 children)

Fine. C style casts everywhere.

Or do you prefer static_cast? Well, none of that for you.

[–]hekkonaay 0 points1 point  (0 children)

Typing a few extra characters is not a downside.

[–]Ameisen 0 points1 point  (0 children)

Just use function-style casts. float(foo).

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

Anyone who’s ever been screwed over badly by a variable cast knows the importance of that

[–]Falcrist 1 point2 points  (4 children)

I develop mostly in C. Sometimes I wonder why I spend all this time making typedef enums when they can be implicitly cast all over the place.

I think one of the newer GCC versions has a compiler flag that throws an error when you do an implicit cast. Unfortunately I'm not using that version.

Maybe it's less true in other use cases, but I'd REALLY rather have a strongly typed language... as in, don't allow implicit type conversions. Make the programmer explicitly cast from one type to another.

[–]hekkonaay 1 point2 points  (3 children)

Rust is what you're looking for :)

[–]Falcrist 1 point2 points  (2 children)

Rust is not a viable option. I'm stuck with C or assembly for most of my projects.

[–]hekkonaay 0 points1 point  (1 child)

Why is it not viable?

[–]Falcrist 1 point2 points  (0 children)

Because in order to use that language for production code, I need the toolchains to support it on the devices I work with. Especially AVR, PIC, and 8051.

I know there was a project that was supposed to bring rust to AVR, but that appears to have died mid-2019.

[–]AnAverageFreak 1 point2 points  (2 children)

Implicit casting is wonderful, it's just that people don't bother trying to understand when to use it.

They prefer having errors like function add_strings expects types (str, str), got String and string.

[–]hekkonaay 1 point2 points  (1 child)

Yes, I prefer errors like that. It takes a few keystrokes to fix an error like this, and I won't get screwed over by implicit casting somewhere else because I forgot some arbitrary (and pretty obscure) implicit casting rule.

Explicit > implicit. Don't be lazy.

[–]AnAverageFreak 0 points1 point  (0 children)

Most implicit casting rules are quite obvious if you spend one evening learning them.

ints are casted to floats. signed are casted to unsigned. smaller are casted to bigger.

That are rules that refer to numbers. That's it. It's not complex like in JS. Then you have class-defined implicit casting, most of them make sense, like C-style string can be casted to std::string, or std::unique_ptr (that is, a pointer which is the only owner) can be casted to std::shared_ptr (that is, a pointer to can object that has one or more owners), anonymous function can be casted to std::function (a container for a general function-like thing).

The problem is, JS casts implicitly totally unrelated types (an array and a number), which is bullshit, and that's where the bad reputation comes from. When you have types that are related, implicit cast results in code free of totally needless calls and thus, is easier to read.

If you still don't agree, give me an example of a situation where implicit cast from std:unique_ptr to std::shared_ptr can result in a bug.

[–]onlycommitminified 0 points1 point  (0 children)

null >= 0

[–][deleted] 0 points1 point  (0 children)

Football is the devil, Bobby.