[HN Gopher] Google broke a conditional statement that verifies p...
___________________________________________________________________
Google broke a conditional statement that verifies passwords on
Chrome OS
Author : stalfosknight
Score : 139 points
Date : 2021-07-22 18:32 UTC (4 hours ago)
(HTM) web link (arstechnica.com)
(TXT) w3m dump (arstechnica.com)
| jeffbee wrote:
| This is clearly a typo that happened to stomp some logic that is
| not covered by a test. The review 3002282 includes the bug, which
| deletes one of the & from a && operator. It says it was cherry-
| picked from review 2994464, which does not change that line. So,
| slip of the backspace key plus poor testing.
| tyingq wrote:
| Yeah, the biggest thing to me here is that there's no "login
| succeeded" unit test, integration test, manual test, etc.
| Whatever customer logged in first was the first person to
| actually run the code.
| SahAssar wrote:
| Just reading the title it sounded very much like "Single Point of
| Failure: The (Fictional) Day Google Forgot To Check Passwords":
| https://www.youtube.com/watch?v=y4GB_NDU43Q
| jedimastert wrote:
| I love Tom's speculative fiction talks. He tells such a good
| story.
| lmilcin wrote:
| Umm... no automated tests? Junior engineers responsible for
| security of half of the world without proper code review?
| tpmx wrote:
| Half of the world? We're talking primarily north-american
| school kids.
|
| https://trends.google.com/trends/explore?q=chromebook
| wil421 wrote:
| Can the link be updated to the one below? The link above goes
| directly to the comments section and collapses the article,
| ?comments=1 is the culprit.
|
| https://arstechnica.com/gadgets/2021/07/google-pushed-a-one-...
| stalfosknight wrote:
| HN won't let me edit the URL. :/
| wil421 wrote:
| Dang or someone else will probably see it. I didn't think
| you'd be able to do it yourself.
| dang wrote:
| Fixed now. Thanks!
| dboreham wrote:
| This has happened so many times in recent years to high profile
| services and OSes. You'd think it'd be a test case.
| black_puppydog wrote:
| That's not "bricking" as the title suggests. Sorry, word police
| incoming. :P
| snvzz wrote:
| What it means is: They push crap to users with no testing.
|
| Testing would have caught this.
| schemescape wrote:
| Maybe pushing updates to users _is_ their test process? I doubt
| they 're the only ones doing this, sadly.
| [deleted]
| Traster wrote:
| I bet the post-mortem for this is going to be fun. How this
| wasn't covered by multiple unit tests, a code review and a roll
| out strategy is.... impressive.
| sneak wrote:
| Bitwise & versus logical && is a classic, right up there with
| an assignment in a comparison (when an equality check is
| intended), = for ==.
|
| That this was missed is pretty surprising, given that it's
| Google and the stakes involved in the encryption/key management
| code in a secure platform device.
|
| I wonder if we'll even get a postmortem, as this simply cannot
| happen unless several someones all Seriously Fucked Up
| simultaneously.
|
| - code error (expected, humans are fallible)
|
| - review error (less expected, this is the kind of thing code
| review exists for)
|
| - static analysis / linting check failure
|
| - integration test failure (interactive login no longer works
| on this build)
|
| This is a massive, overlapping fuckup. Heads should probably
| roll here, especially given that when you opt in to ChromeOS as
| a user, Google now has "one job" (DFIU).
| nogridbag wrote:
| I've seen the = instead of == in the wild with disastrous
| results: the assignment was on an ORM backed object, e.g.
| // accidentally mutates all names to Sam and persists to the
| DB myList.filter { myDomainObj.name = 'Sam' }
|
| But it makes me wonder why our programming languages would
| use characters which can often lead to this type of error.
| sneak wrote:
| If you consider a linter part of a programming language,
| most, when properly configured, do not permit this. It's
| just the syntax that does; professionals do not rely on
| syntax validity alone but employ linting, code review,
| static analysis, and integrations tests on top.
|
| The gradient of professionalism in our industry is very
| wide, and the slope is quite shallow.
|
| To your point, however, many languages (such as Go,
| developed and used by Google, the organization under
| discussion) have designed their syntax now to completely
| avoid this type of error even being possible.
| galangalalgol wrote:
| what is the difference between linting and static
| analysis? Coverity, cppcheck etc, what are those? You
| mention integration tests, but not unit test, do you
| value unit test?
| tmp_anon_22 wrote:
| > type of error even being possible
|
| I mean its still possible to forget the ":" character and
| its still possible to mentally scan a PR and see "=" and
| miss that it should have been a "==".
| edflsafoiewq wrote:
| = vs == isn't possible in Go because of the
| statement/expression distinction. The benefits of
| allowing assignment to be an expression are too small
| compared to the problems it causes. x ==
| 1 // oops, meant = // x == 1 evaluated but not used
| if x = 1 { ... } // oops, meant == // syntax error:
| assignment x = 1 used as value
| nightfly wrote:
| I'm a fan of programming languages using := for assignment
| for this reason
| AnimalMuppet wrote:
| Look, I know that this is an enormously bad bug, but...
|
| Google has a codebase that numbers multiple billions of
| lines. Using := means typing multiple billions of extra
| characters. That adds up. And it wouldn't even have
| prevented this bug!
|
| All checks have costs. As Emerson said, "A stitch in time
| saves nine. So we make 1000 stitches, that by doing so we
| may save nine."
| anyfoo wrote:
| Once more I hope this is satire, but as so often on the
| Internet it is surprisingly hard to tell.
| samtheprogram wrote:
| This reminds me of Silicon Valley's main character
| preferring tabs to spaces because they use less bytes,
| despite his own product being for... compression!
|
| I personally prefer spaces so that under any
| circumstances, the code reads the same as the author
| intended (whether you're in an editor or viewing a file
| with a CLI tool). Are we really counting bytes in this
| day and age?
| anyfoo wrote:
| The problem is not even with "easy to mix up operators" for
| this, it's about languages without a strong and static
| enough type system. While the particular problem Google hit
| is a bit more subtle (involving undefined behavior), in the
| majority of cases a strongly typed language would not allow
| expressions that accidentally mix up = and ==, as they
| often resolve to different types.
|
| In C "if (foo = bar)" and "if (foo == bar)" are both legal,
| because pretty much any type can be automatically coerced
| into a boolean. In many modern languages that is not the
| case. (Of course if you have assignments as expressions you
| are still screwed if foo and bar are both boolean to begin
| with, so some languages got away with that, too. And for
| fairness I should say that C at the very least warns if you
| don't explicitly put parentheses around the assignment,
| nowadays.)
| crazygringo wrote:
| > _in the majority of cases a strongly typed language
| would not allow expressions that accidentally mix up =
| and ==, as they resolve to different types._
|
| That's not true at all.
|
| Whenever you're intending to compare equality, they're
| usually going to be the same type _already_ unless you
| 're being really slopping in a scripting language like
| JavaScript or PHP -- but even then they're _usually_ two
| numbers, two strings, or two booleans.
|
| The whole problem here is where foo and bar are _both_
| integers, or booleans, or whatever you want, and instead
| of typing "if (foo == bar)" you type "if (foo = bar)".
|
| Strong typing does _nothing whatsoever_ to help in this
| common situation.
| anyfoo wrote:
| No. It can help because the _result_ of the expression
| would have a different type, one that "if" does not
| accept. If a and b are integers, then the expression "a =
| b" is an integer too, but "a == b" is a boolean. In a
| strongly typed language, you can assume that "if" only
| accepts booleans.
| Guidii wrote:
| "Heads should probably roll here..."
|
| Google has a blameless post-mortem process (see
| https://sre.google/sre-book/postmortem-culture/) which
| essentially boils down to:
|
| 0) We want to fix the situation. By the time the post-mortem
| happens, that should already be done.
|
| 1) We want to make sure this never happens again. In order to
| do that we need to understand as much as we can about what
| happened.
|
| 2) We want everyone to share everything they know about the
| event. If the participants worry about fallout, they will be
| compelled to cover up.
|
| 3) Most failures happen at a number of points, so you need to
| dig in deeply if you want to get full value out of the
| "event".
|
| 4) Good post-mortems lead to process fixes to reduce (or
| eliminate?) the chance of similar events, or to make fixes
| throughout the code base.
|
| The other thing is that after the post-mortem, all of the
| folks involved have learned from it. Usually they're better
| engineers because of that expensive lesson you've just paid
| for.
|
| Disclaimer: Googler, participant in several post-mortems,
| opinions my own.
| agilob wrote:
| RedHat once committed wrong value of MTWO variable, it was 2,
| there was another variable called TWO which also had value of
| 2. It was fixed a few months later with a commit like "change
| value of MTWO to -2".Sorry, but can't find it find now
| james_in_the_uk wrote:
| Straight up negligence.
| kps wrote:
| I'm quite surprised there isn't a compiler warning for a
| bitwise operator at the root of a condition. I've been
| writing `if ((flags & FLAG) != 0)` for decades years for
| nothing?!?
| fierro wrote:
| _glances at screen_ LGTM
| brundolf wrote:
| Especially since it's so easy to lint for. This isn't some
| cross-file memory mishandling bug, it's a single token that's
| being used where it shouldn't be
| mdoms wrote:
| > Heads should probably roll here,
|
| I disagree. It's obviously a major balls up by multiple
| people, but at the end of the day this is an organizational
| failure. You don't fire people for this, you learn from it
| and fix the organizational holes that caused it.
| sneak wrote:
| Someone is responsible for the organizational units and
| their processes.
|
| By that logic, almost no individual failure is a firing
| offense. Many people in the organization are responsible
| for ensuring that the processes themselves overlap in ways
| that exclude the possibility of failures like this.
|
| I'm talking about the meta-failure in management's
| oversight of the processes. There is belt person, and there
| is suspenders person, and there is a third person who makes
| sure there are both belt person and suspenders person on
| staff and that they don't go on vacation at the same time.
|
| Somewhere above the team lead and below the CEO there is
| someone who didn't do their job.
| nicoburns wrote:
| > By that logic, almost no individual failure is a firing
| offence
|
| I'd probably agree with that. Firing should be for
| extreme negligence, or sustained underperformance.
| idiotsecant wrote:
| >extreme negligence
|
| If this doesn't qualify, what does?
| vlovich123 wrote:
| This isn't extreme negligence of any single individual.
| If there are linters/compiler warnings that should have
| caught this, this is an organizational failure that can
| be remedied and the manager/TL should be taking a bit of
| a hit here as having those enabled is best practices.
| Since it's ChromeOS I imagine there's a dedicated team
| managing the build infra and it's not using the base set
| of things that Google3 protects you with, so the fault
| may lie in that organization a bit as an oversight.
|
| Then there's obviously the automated testing strategy,
| manual testing strategy and sanitizer strategy that
| missed this.
|
| The net result is extreme negligence but to me this kind
| of failure speaks to several layers going wrong at once
| rather than one person fucking up badly. Organizationally
| you try to defend against these kinds of failures with
| multiple layers of defenses.
|
| Now if this was a malicious internal attack that should
| be investigated but I'd hate to have to seriously
| reprimand anyone who typo'ed & instead of &&.
| ectopod wrote:
| The GGGP is talking about failures at a higher level. Not
| reprimanding the coder who missed an ampersand, but the
| manager who was ultimately responsibly for ensuring there
| was a functioning process for catching this sort of
| nonsense.
| sneak wrote:
| I would say this is negligence, but perhaps not extremely
| so.
| anyfoo wrote:
| You are all very quick to judge. I don't work for Google
| so I don't know what happened, but consider the
| possibility that this may have been a freak accident.
| That piece of code for example might only be on a path
| that is not activated when testing, or it may be executed
| but not have the same fatal effect.
|
| And before anyone comes along and says "well, every
| possible path should be tested then": That would be
| absolutely impossible even if the halting problem wasn't
| a thing (which it very much is). Even if you somehow have
| utopian "100% code coverage", that does not mean you have
| tested every possible input resulting in every possible
| state combination.
|
| I bet every one of us has a story about an old bug that
| only manifested years[1] later because of the confluence
| of many unfortunate things, one that takes half an hour
| to tell.
|
| [1] Or even decades, in some cases that then made it to
| the HN front page.
| nicoburns wrote:
| This is the sort of thing that most linting tools will
| catch, so it's a bit worse than that I think. You
| shouldn't need _any_ test coverage to catch this.
| admax88q wrote:
| The way you fix organizational/process failures is not by
| firing the person in charge of them every time they fail
| to catch something.
|
| How many breaking bugs have _NOT_ shipped due to the
| current processes. Your approach suggests that there is
| some perfect process manager out there who will let no
| bugs like this ship (whilst not dropping any other
| business priorities mind you) that they just haven't
| hired yet into this position.
|
| This isn't as big of a bug as people on HN want it to be.
| A few months from few people will remember, and even
| fewer will care.
| AnimalMuppet wrote:
| There is a story (perhaps apocryphal) of a salesman who
| lost a $10 million deal for IBM. He was sure he was going
| to be fired. Some bigwig (Watson himself, maybe?) talked
| him through what had gone wrong. The salesman asked,
| "Aren't you going to fire me?" The bigwig said, "I just
| spent 10 million dollars training you."
| yupper32 wrote:
| > By that logic, almost no individual failure is a firing
| offense.
|
| That's pretty close to how it should be. That's the core
| premise of the no-blame post-mortem culture that's great
| about some companies.
|
| As long as you go through the port-mortem process, which
| includes doing your best to prevent this from happening
| again (which may include changing organizational
| processes, testing strategies, etc), then everyone can
| move on with their lives.
|
| Firing happens when you have a history of performing
| below your level. Never for a single engineering failure.
| sneak wrote:
| This isn't an engineering failure. Everyone writes bugs.
| yupper32 wrote:
| Engineering process is still engineering in my book, but
| if it helps:
|
| Firing happens when you have a history of performing
| below your level. Never for a single process failure.
| mdoms wrote:
| > By that logic, almost no individual failure is a firing
| offense.
|
| Correct.
| aeturnum wrote:
| I don't think we know enough from this to say.
|
| It's possible that this bug made it into the wild because
| the organizational structure made remedies impossible. In
| that case you probably don't fire anyone, though maybe you
| reassign some folks.
|
| It's also possible that the organizational structure
| indicates that a person or a group of people is responsible
| for this and they failed to do that job. If that's the case
| then it might very well make sense to fire folks. It also
| might not.
|
| I think it's important for poor performance to have
| consequences[1] and I also think that people leave jobs all
| the time and it's fine to decide that someone should leave
| their place in the org with a positive reference and look
| elsewhere for work (perhaps in another part of goog).
|
| [1] for moral and company culture reasons if nothing else.
| chovybizzass wrote:
| i've never worked on a project (even TDD) that did that level
| of testing detail.
| contravariant wrote:
| Wait so are the devices bricked or not? The title says bricked
| but as far as I can tell people just can't log in temporarily
| until the fix is rolled out.
| penagwin wrote:
| It's a soft lock for sure, given it requires a software update
| to use you could likely consider this a soft brick too.
|
| It's not a hard brick to your point.
| dang wrote:
| Ok, we've done our bit to counter brick dilution in the title
| above.
| sneak wrote:
| No, they are not bricked. The term has become ridiculously
| diluted in practice to mean "hard, breaking bug".
| secondcoming wrote:
| Edit: Someone has explained the issue below
|
| I don't understand how that broke anything?
|
| The C++ codegen for && and & is the same: bool
| good(bool a, bool b) { return a && b; } good(bool,
| bool): mov eax, edi
| and eax, esi ret bool bad(bool
| a, bool b) { return a & b; } bad(bool, bool):
| mov eax, edi and eax, esi ret
|
| [0] https://godbolt.org/z/84MMqTehs
| taeric wrote:
| The short circuiting was preventing undefined behavior on the
| second expression.
|
| That is, yes, it is the same with booleans. Now try with
| expressions.
| formerly_proven wrote:
| The code is: key_data.has_value() &&
| !key_data_->label().empty()
|
| key_data is probably something like an std::optional, so short-
| circuit evaluation guards the dereferencing of the optional. If
| you write this with a binary and, no short-circuit evaluation
| can happen, so undefined behavior ensues.
|
| I wanna point out that std::optional, in the typical C++
| stance, has a "I know what I'm doing" API and a "Humans make
| mistakes API": optional->... is UB if the optional is empty,
| optional.value()... raises an exception. Arguably, in code like
| this you probably only want to use the latter kind of API. (The
| pattern of "operator can UB, equivalent method asserts pre-
| condition" is very common in the C++ standard library)
| jeffbee wrote:
| Correct, key_data_ is a base::Optional<KeyData>. Chromium's
| base::Optional is very similar to std::optional, but predates
| c++17.
| tmiahm wrote:
| The difference is your example uses bool values, the code in
| question uses expressions that (should) evaluate to bool. && is
| short-circuited if a is false, such that b is not evaluated.
| [deleted]
| skinkestek wrote:
| The company who no longer recognizes doublequotes nor their own
| verbatim operator?
|
| The one who flags chess videos?
|
| Closes decade old accounts without any kind of explanation?
|
| Absolutely believable.
|
| Wouldn't surprise if this too is related to relying on their
| Artificial Stupidity^HIntellingence systems.
| iamcreasy wrote:
| The article says the problem bricked their laptop - but I was
| under the assumption that you can create a non-google
| account/guest account on Chrome OS to use the device.
| tuxoko wrote:
| I haven't touched C++ in forever, but as a C programmer it looks
| insane that you can do dot operator and -> operator on the same
| variable and not cause compiler error...
| tyingq wrote:
| I'm baffled that there's no test for this, manual or otherwise,
| before this rolls out to production. That you can change ChromeOS
| code in the login path, and the very first time it's exercised is
| by an end customer.
| mouzogu wrote:
| Couldn't this be caused by a bad merge?
|
| Not sure how Google manages their merging and release process but
| there are conceivably several stages where a bad merge can occur
| and go unnoticed - possibly at a stage close to release and after
| testing.
| tmp_anon_22 wrote:
| At an established company merging is an incredibly incredibly
| locked down process. There are usually multiple barriers of
| automation and people, entire release teams who all have to be
| stoned at the wheel to miss anything odd getting through.
| fouric wrote:
| From the article:
|
| > The line should read "if (key_data_.has_value() &&
| !key_data_->label().empty()) {" but instead of "&&"--the C++
| version of the "AND" operator--the bad update used a single
| ampersand, breaking the second half of the conditional statement.
|
| Someone correct me if I'm wrong, but this seems like it wouldn't
| be possible in a language that didn't conflate boolean values
| with bitvectors.
|
| Edit: I was wrong[1].
|
| [1] https://news.ycombinator.com/item?id=27923785
| CobrastanJorji wrote:
| Forgive my poor C++, but has_value() sounds like a bool, and
| empty() sounds like a bool. Why wouldn't "bool1 & bool2" work
| correctly?
| kevinmgranger wrote:
| If I had to guess, the second expression depends on the first
| being true. So if `has_value()` is false, perhaps
| `key_data_->label()` is undefined behavior.
| dataflow wrote:
| Dereferencing via key_label_-> has undefined behavior when
| !key_label_.has_value(), so the compiler treats that case the
| same as if key_label_.has_value(). Or to put it another way,
| the compiler reasons that key_label_ must have had a value
| (since you dereferenced it), and thus optimizes out the check
| for `has_value()` (since clearly it was unnecessary).
| myko wrote:
| Would this optimization not have been on the beta/canary
| channel? I assumed they were but perhaps not since this was
| not caught.
| dataflow wrote:
| I don't know how their builds work or where their
| templates are instantiated but it's possible that the
| compiler doesn't see this optimization until LTO and that
| they don't do LTO until stable releases? It would seem
| strange though, I'd have thought beta would have LTO.
| anyfoo wrote:
| Yeah that would be a very weird choice. LTO itself can
| have bugs, or (as we speculate here) unmask existing
| bugs. Plus, even that aside, you'd hopefully test exactly
| the build that you will release before you release it.
|
| As I wrote in another comment, this could still be the
| result of a freak accident and not have shown up in
| testing, though (but since I know nothing about the
| process or the code there, it could be anything).
| fouric wrote:
| Ahhh, so it was a problem with lazy evaluation (and the
| lack thereof when using &), and not type coercion, like I
| initially thought.
| kbelder wrote:
| I think this is a unpopular opinion, but I consider
| taking advantage of short-circuiting in boolean
| operations to be a code smell. At least for me, it seems
| very fragile and I'd much rather break the conditional
| logic out explicitly.
|
| But I like to write as much like assembly as I can in
| every language. Each line of code should do one and only
| one thing.
| dataflow wrote:
| I used to only put short-circuits when I really needed
| short-circuit behavior, thinking it improved readability.
| But after getting by the implicit type conversions over
| and over (as well as nags from every compiler) I just
| decided it was a bad idea in C++. I'd still do it in a
| safer language, but in C++ I'm convinced you should just
| use && even when you only need & for bools.
| dataflow wrote:
| Yeah it has nothing to do with type coercion. I'm baffled
| a linter doesn't catch this though. & for bools should
| just be prohibited altogether. If people really want &
| for bool, they can just cast to an integer type and use &
| with that (which generates its own warnings
| appropriately).
| gpderetta wrote:
| the problem is that bitwise & and | are routinely used
| for their non-shortcircuiting behaviour in boolean
| expressions, so it is hard for the compiler to flag this
| as an error.
|
| Many linters and static analysis tools do flag them
| though as these days it is not considered good practice.
| anyfoo wrote:
| Why would you even need non-shortcircuiting behavior in
| boolean expressions? Because either side of the operator
| has side effects that you want to happen unconditionally?
| Please just write it out as an extra statement then
| instead of hammering it into place with an implicit
| coercion to an integer type only so you can abuse bitwise
| AND and OR only to force that side effect to... you can
| see why this is probably not the most elegant idea.
| slavik81 wrote:
| Matt Godbolt gave an example of a significant performance
| hit caused by unnecessary short-circuiting in his CppCon
| 2019 talk[1]. EDIT: Deleted tangent.
|
| [1]: https://youtu.be/HG6c4Kwbv4I?t=45m
| dataflow wrote:
| > & and | are routinely used for their non-
| shortcircuiting behaviour in boolean expressions
|
| Really? I can't recall a single case of this with 'bool'
| in any codebase in my recent memory. I only see it with
| integers. And even if it's somehow routine for your
| codebases with bool (why?!), surely it's not routine
| inside a _conditional expression_ , so at least they can
| prohibit it there?
| xmprt wrote:
| So instead of short circuiting like that code should when
| it uses &&, it instead makes an assumption about the first
| part of the boolean expression because otherwise the code
| would have undefined behavior?
| dataflow wrote:
| Yeah. More specifically, it just inserts whatever
| behavior it likes for the undefined scenario, which in
| this case is "the same behavior as in the defined
| scenario".
| grishka wrote:
| Certainly won't compile in Java.
| taeric wrote:
| Oddly... It would? Try: Map<String,
| Boolean> map = ... if (map.containsKey("hello") &
| map.get("hello")) { ...
| shawnz wrote:
| In fact you can apply the single ampersand & operator to
| booleans in Java, and just like in the example here it has
| the same behaviour as && but with no short-circuiting.
| grishka wrote:
| Huh. I didn't know that.
| wyager wrote:
| The most general solution here is to use algebraic types and
| pattern match on the value being "None" or "Some data".
| Trollmann wrote:
| You can use `and` and its siblings instead of && and similar in
| C++11. Most people here, and in other boards, will try to
| convince you that it hurts readability because 'that's how we
| always did it' (read I'm used to it and don't like change).
| gavinray wrote:
| I was surprised to read that `and`, `and_eq`, `xor`, etc are
| all supported "secondary/alternative operators"
|
| Never seen them used, but I use them in my C++ code when I
| have to write it to accomplish something else:
|
| https://en.cppreference.com/w/cpp/language/operator_alternat.
| ..
| inetknght wrote:
| I used to use them. Then I was burned by some Very
| Opinionated managers and coworkers who didn't like seeing
| new things. It wasn't a hill I was willing to die on;
| there's more important things to argue about in C++.
| fouric wrote:
| I am also of the opinion that `and` is more readable than
| `&&` (and isn't as easy to typo in a catastrophic way) -
| although my main point was about the weaker type system.
| qalmakka wrote:
| C++ definitely hasn't a weaker type system than "newer"
| languages like Java - if any, it is much more richer and
| complex than most languages out there. What's happening
| here is a type conversion that has to be in place due to C
| not having a boolean type until 1999. C++ attempts to
| construct a boolean from the argument of an `if()`, and
| given that bool can be constructed from int, the conversion
| succeedes.
|
| You can define your own conversion operators to boolean,
| too, which are very useful for stuff like smart pointers
| and similar classes that may or may not have a value.
| struct A { std::string value;
| explicit operator bool() const { return
| this->value.size(); } }; // ...
| A a {}; if (!a) { // ... }
| fouric wrote:
| "Not as weak as Java" is not a very interesting
| benchmark, as Java _also_ has a poor type system. C++ 's
| type system is pitiable relative to those of Rust,
| Haskell, OCaml, and SML.
|
| Moreover, in addition to being less expressive than them,
| C++'s type system is also _weak_ , in formal sense, by
| allowing many implicit type conversions - which is one of
| the issues that I was complaining about. The fact that it
| "has to be in place due to C not having a boolean type
| until 1999" doesn't make it any less weak.
| dylan604 wrote:
| That so sounds like an error I would make and not some superDev
| working at the Googs making around 4x the amount of money I
| make.
| myko wrote:
| They're just people. If you want to get in you probably
| could, with some effort.
| anyfoo wrote:
| Not sure why you think a "superDev" would be less susceptible
| to simple typos?
| [deleted]
| shawnz wrote:
| Other than this particular edge case it's not obvious to me why
| bitwise operators shouldn't be applicable to boolean values.
| Aren't they just single-bit vectors?
|
| Of course it makes sense that logical operators wouldn't be
| applicable to numeric types, but why the reverse?
| phkahler wrote:
| >> Other than this particular edge case it's not obvious to
| me why bitwise operators shouldn't be applicable to boolean
| values.
|
| That is a really good question. At some point they decided
| that true=1 and false=0 but I'm not sure how deep that goes.
| In particular what does ! actually do in this context?
| qalmakka wrote:
| If you stop integer values from being implicitly convertible
| to booleans, you break the language and its compatibility
| with C.
|
| The inverse is debatable, though. I honestly don't see why
| someone would do bitwise operations on boolean, unless they
| really wish to die a slow death from thousand cuts. Integer
| promotion rules make even the simplest operations a wild
| mess, and there's nothing in the standard that prevents bool
| from having a sizeof equal to int (thus further complicating
| everything).
|
| It might be sensible for newer language revisions to consider
| deprecating certain operators from being applied to bool,
| given that there is a strong change that 99% of the time
| their use is not on purpose, but I guess it depends on how
| much disruptive such change would turn out to be.
| shawnz wrote:
| I don't think the other poster was imagining a language
| that retained compatibility with C, but rather a new
| language altogether. Of course it would be impossible to
| change this aspect of the language if retaining
| compatibility with C was a requirement.
|
| > I honestly don't see why someone would do bitwise
| operations on boolean
|
| For example, you might _want_ the behaviour shown here of
| not short-circuiting. Or you might want to create a bitwise
| function that also allows calling on single-bit (i.e.
| boolean) values.
| gmfawcett wrote:
| This is one of those times when, for all its verbosity, Ada got
| it right. For boolean conjunction you must choose between
| writing "A and B", or "A and then B". The "and then" version is
| short circuiting, while the bare "and" version is not.
| gene91 wrote:
| This is a typo of missing an ampersand. If the author were
| writing Ada, it would have been a typo of missing a "then".
| How is it different?
| shawnz wrote:
| Visual Basic also has this distinction (but the keywords are
| "And" and "AndAlso")
| dolni wrote:
| If you've been in tech for a while, this is one of those things
| that makes you sigh and shake your fist at "move fast and break
| stuff" as a strategy.
| ipsum2 wrote:
| Google's philosophy isn't "move fast and break stuff". It's
| probably the opposite - "move slow and be careful". These
| things happen.
| throwntoday wrote:
| That's more about challenging the status quo not bad project
| management.
| Animats wrote:
| The reason this happened is that it wasn't followed by "Google
| hit by 143 defective product lawsuits".
| kevincox wrote:
| I don't think they could possibly be sued for this. They would
| just be responsible for fixing or refunding the product. In
| this case they issued a "fix".
|
| It is the same as when a car is defective. They don't get sued,
| they do a recall and fix it.
___________________________________________________________________
(page generated 2021-07-22 23:00 UTC)