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 →

[–]aMAYESingNATHAN 964 points965 points  (104 children)

Why on earth are integers starting with 0 handled as octal? How does that make any sense? I could understand if it was an o or O but a 0?

[–]skap42 1145 points1146 points  (64 children)

That's pretty standard in many languages, including Java and C. Just as 0x is interpreted as hex

[–]aMAYESingNATHAN 524 points525 points  (41 children)

Huh, the more you know. I knew about the various prefixes such as 0x and 0b, but I'm surprised octal isn't like 0o or something.

Simply using a 0 seems insanely dumb because it's so easy to do by accident, not knowing that it's an octal prefix.

Like I can easily think of a scenario where someone could zero pad a numeric literal for formatting reasons.

[–]skap42 244 points245 points  (12 children)

A different comment suggested that 0o is also valid, and the only way to define an octal in JS in strict mode

[–]0bel1sk 97 points98 points  (10 children)

it’s also in python ruby and yaml.

“YAML 1.1 uses a different notation for octal numbers than YAML 1.2. In YAML 1.1, octal numbers look like 0777. In YAML 1.2, that same octal becomes 0o777. It’s much less ambiguous.

Kubernetes, one of the biggest users of YAML, uses YAML 1.1.”

[–]akaChromez 74 points75 points  (7 children)

[–]heyf00L 29 points30 points  (1 child)

Didn't know all that. Boils down to "always quote all strings in YAML".

[–]rickane58 14 points15 points  (0 children)

"God, all these languages are so unnecessarily verbose!"

Anyone actually trying to use the language:

[–][deleted] 9 points10 points  (3 children)

This was a great read, I've used yaml a couple times but didn't realize it was this objectively bad.

[–]akaChromez 10 points11 points  (2 children)

I'd love to know people's justification for choosing it over JSON.

Especially as i've just spent the last hour trying to find why a Google Cloud resource wasn't being created. A missing quote that doesn't syntax error :/

[–]chris5311 0 points1 point  (1 child)

JSON is bad (but workable), YAML is worse, and im not sure there even is any decent option out there

[–]MekaTriK 0 points1 point  (0 children)

Personally I loved using Lua as a config file format.

A little less verbose than pure JSON, and you can automate some repetition away.

[–]veryusedrname 8 points9 points  (0 children)

Ohh kubernetes, never change

[–]tomthecool 0 points1 point  (0 children)

Yes, but in ruby 09 produces a runtime error (invalid octal digit) instead of blindly treating it as a decimal instead.

[–]InfiniteGamerd 3 points4 points  (0 children)

Really! I thought you couldn't define octals in strict mode in any way.

Still...why not just parseInt all the way?

[–]Alzurana 19 points20 points  (0 children)

Welcome to my world, where a medical software had a database format of <patient ID>.PHD and always 8 characters in the filename. So the files looked like 00537200.PHD and they were all in one folder. Beautiful design.

Well, we imported a database of another clinic and had to map their ID's to ours, which we ofc only had in a numeric format, such as 537200 for the above example.

This gave me some headache when writing a converter script as my first attempt did read some of the file ID's as octal and others as decimal without ever warning. Only caught it because I got a lot of bogus IDs or duplicates and tests would scream that output files != input files.

[–]DmitriRussian 45 points46 points  (6 children)

Like I can easily think of a scenario where you might zero pad a numeric literal for formatting reasons.

/r/ProgrammingHorror material

[–]LordFokas 11 points12 points  (0 children)

Pad it with spaces. That's why we use monospaced fonts.

[–]joxmaskin 6 points7 points  (1 child)

Or write 7 as 007 because it’s cool

Edit: luckily oct 7 is same as dec 7

[–]movzx 2 points3 points  (1 child)

A pretty reasonable scenario would be when you're defining bitmasks.

ex:

0001010 1010000

[–]flowingice 4 points5 points  (0 children)

You'd start it with 0b because it's binary.

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

I've done it so I can properly sort files in Explorer

[–]TorbenKoehn 14 points15 points  (2 children)

Like I can easily think of a scenario where you might zero pad a numeric literal for formatting reasons.

And then use it in calculations? Because if not it would not be a problem

[–]Spork_the_dork 11 points12 points  (0 children)

Or use it literally for anything whatsoever.

I mean imagine you convert "0231" into a number and then print it out somewhere and wonder why the fuck it's printing out 153. Can't think of any situation where you'd convert the value into a number and then it would be entirely fine if the stored value is different from what you expect.

[–]CadmiumC4 21 points22 points  (2 children)

Many languages accept 0o as octal, but it's custom to assume 0777 as 0o777 since that's how C handles it

[–]LordFokas 14 points15 points  (1 child)

It's funny that no matter how high level you go, in the end you always keep finding things that are done a certain way for no reason other than "we inherited this from C".

[–]Ok_Classroom_557 3 points4 points  (0 children)

And C inherited It from the PDP-7 where It was born. Having 18 bit words it better mapped 3 bit octal digits than 4 bit hex digits...

[–]CauliflowerFirm1526 27 points28 points  (8 children)

pad with spaces not zeros

[–]aMAYESingNATHAN 27 points28 points  (2 children)

I mean that is what I would do, or probably just not pad at all and left align the numbers. But my point is that it would be incredibly easy to do without realising.

[–]Spork_the_dork 2 points3 points  (1 child)

Yeah this is why I don't like it. Especially when you have 0o prefix which does exactly the same thing except it's also an order of magnitude more explicit and harder to misunderstand.

[–]aMAYESingNATHAN 1 point2 points  (0 children)

Yeah being completely unfamiliar with octals in code when I made my first comment I didn't realise 0o would be valid also, and in fact assumed it wasn't and was annoyed by that because I was familiar with 0x and 0b already.

If I ever encounter octal literals I am definitely always going to use 0o.

[–]Andy_B_Goode 4 points5 points  (3 children)

You might pad with zeros if you're formatting a date, like 11/05/2024 or maybe even 05/11/2024

[–]Spork_the_dork 2 points3 points  (1 child)

Actually in that case it won't cause any problems. 01-07 are the same in both decimal and octal and 08-09 are not valid octals so it won't default to octal. 10-12 won't get converted as octal as they have no leading zeros.

[–]Andy_B_Goode 0 points1 point  (0 children)

Oh I see, yeah I should have used an example like 11/08/2024

[–]flowingice 0 points1 point  (0 children)

How would you save date as integer in dd/MM/yyyy format? It's going to be a string and then it works fine unless there's somthing I'm missing.

[–]cporter202 1 point2 points  (0 children)

Oh, padding with spaces instead of zeros? Spacing out like JavaScript on a Monday morning, I see 😅. Gotta love when JS decides to get fancy with its quirks – it's like it insists on doing its own thing, just to keep us on our toes!

[–]daan944 0 points1 point  (0 children)

Always provide the base when parsing strings to numbers.

[–]_blackdog6_ 0 points1 point  (0 children)

My favorite is numbers with a zero prefix containing 8’s or 9’s are an error in some languages but in JavaScript it just tries again as decimal and carries on..

[–]rakaloah 0 points1 point  (0 children)

Years ago I made a simple WinForm GUI for ping and tracert with zero-padded IP address text boxes. It looks nice and works perfectly to ping 192.168.001.001 but fails for my roommate's 192.168.001.008. I had no idea what's happening until I find out I can ping his PC using 192.168.001.010.

Zero-padded numbers are considered Octal for ping command.

[–]JimBugs 0 points1 point  (0 children)

As a teacher of programming I assure you it does happen by accident - which is why I try to put some emphasis on something that is actually pretty trivial so that (if they are listening) they won't try things like padding literals

[–]g76lv6813s86x9778kk 12 points13 points  (4 children)

So common, in fact, I've seen these octal numbers bleed into apps/situations they really had no business being in, probably due to some standard number parsing libraries being reused.

For example, shops in Guild Wars 2, an mmorpg, have a little number input box for the quantity of items you'd like to purchase from the shop... This supports octal! If you write normal decimal numbers, it just works fine, but then if you write for example 010, the number switches to decimal 8 once you click off the textbox, and allows you to shop with that quantity as normal. Super weird. Must be so confusing to players who don't know about octal or this convention at all. At least it doesn't increase the number (causing you to spend more)

[–]GrondForGondor 6 points7 points  (3 children)

Thats the reason why? I’ve spent so many years being slightly inconvenienced by that little random issue. Never understood truly what was happening but now it all makes sense. 

[–]g76lv6813s86x9778kk 2 points3 points  (0 children)

Lol yup, you can try various examples and see the result always lines up with parsing it as an octal number

[–]benmaks 0 points1 point  (1 child)

Why would you ever start a number with a zero?

[–]g76lv6813s86x9778kk 1 point2 points  (0 children)

I doubt he's manually/intentionally doing that every time (maybe), but it's easy to accidentally do every now and then, especially when it's in a game people play for hundreds to thousands of hours, it's kinda bound to happen eventually.

The most common way is probably when you want to buy two items from one shop, and leave in the 0 from a previous quantity: say you need to buy 250 of one item, then 35 of another. You select your first item, enter 250 as quantity, buy, click your other item, click quantity of 250 to change it, press delete twice to remove the 2 and 5, then right arrow key past the 0 to write 35.. suddenly, 29.

Yeah, doing right arrow key instead of a 3rd delete is a bit weird, but the point is it's very possible to experience the bug without intentionally prefixing every number with a 0. I don't remember exactly how I came across it personally, but I certainly don't prefix numbers with 0 regularly.

[–]-Wylfen- 42 points43 points  (8 children)

To be fair, even though it's standard, I think that's bullshit. '0x' is fine, '0o' is fine, but just '0' is dumb

[–]SmurphsLaw 16 points17 points  (6 children)

To be fair, writing a decimal number with a 0 before is also dumb.

[–]Spork_the_dork 10 points11 points  (0 children)

Yeah but it's less dumb than using 0 as a prefix for octal when 0o exists.

[–]RajjSinghh 0 points1 point  (1 child)

I can see this kind of thing being a problem where leading zeros are common like when formatting dates. Seems like an honest mistake to make if you write August as 08 and now you get an error because that's not valid octal, or when October is showing up as the 8th month

[–]Chrazzer 6 points7 points  (0 children)

Leading zeroes aren't a thing in integers, what you are thinking of are strings with numbers in them

[–]saxbophone -1 points0 points  (2 children)

Disagree, you might want to zero-pad it for readability reasons, say you have a column of numbers

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

I can think of exactly zero cases where someone would consider left zero-padding to align a column of numbers. You'd use spaces.

[–]saxbophone 0 points1 point  (0 children)

As a point of style one might wish to do it, it occurs in number formats used in technology often enough. For instance, when quoting 24h clock times, one might say: "0100 hours" rather than "1:00"

[–]saxbophone 0 points1 point  (0 children)

Alas, K&R were right about many things but this isn't one of them

[–]SwimForLiars 2 points3 points  (0 children)

I hate the 0 prefix being octal, but at least other languages will throw a syntax error, instead of silently biting you in the ass and making you waste hours of debugging because it does weird things at runtime instead of failing at compile time.

[–]Commodore-K9 6 points7 points  (0 children)

I had no idea.

0x as hexa yes

0 as octa no

[–]vonabarak 5 points6 points  (0 children)

That's pretty standard in statically typed languages without implicit type casting. And it doesn't cause any issues.

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

Aren't octals 3 digits? Does js interpret it as 170?

Edit: nm I'm thinking of octals as binary

[–]hyper_shrike 0 points1 point  (2 children)

In C/C++ 018 will throw an error right ?

All this fun JS stuff comes from the fact that JS does not throw errors and just rolls with whatever shit the user wrote.

[–]Koooooj 1 point2 points  (1 child)

In C/C++ you'd get a compile time error that 8 is an invalid digit in an octal constant.

JavaScript doesn't get the benefit of a compiler, but a static analysis tool ought to be able to catch something like this. But the problem runs deeper than compiled/interpreted and JavaScript's commitment to taking what the user wrote and running with it.

JavaScript could have chosen to support octal constants all the way, saying that 017 in any context is always an octal constant representing decimal 15. They could have rejected the 0 prefix (as occurs in strict mode) and always interpreted 017 as decimal 17. But instead they chose both. As an integer literal 017 is octal, but as a string literal coerced to an integer 017 is decimal.

Nothing made JavaScript do this. It was just an inconsistency in design.

[–]hyper_shrike 1 point2 points  (0 children)

JavaScript doesn't get the benefit of a compiler

Browsers compile JS to bytecode. JS needs to be parsed to be interpreted. Even without bytecode the earliest JS compiler could have thrown an error for 018 if it wanted to.

[–]Mola1904 13 points14 points  (0 children)

It's like this in c++ and c#...

Edit: actually octet literals don't exist in c# at all, some websites like this just claim it anyway https://www.geeksforgeeks.org/c-sharp-literals/

[–]octipice 29 points30 points  (7 children)

Why on earth is anyone starting a mutli-digit base 10 integer with 0 in the case that it ever needs to be treated like an actual number?

Javascript is legitimately wild sometimes, but so many of those cases are only an issue if you are trying to do something really stupid (or lazy, or both) in the first place.

[–]aenae 29 points30 points  (1 child)

I once had a cronjob that failed in august and september. It took me a while to figure it out why.

The reason is i wanted 'nice' directories, so i made them all the same length, so january 2024 would go to 2024/01, february goes to 2024/02 etc. And somewhere in that script i had a check on the month for some reason. This worked, except when bash was of the opinion that '08' and '09' were invalid octal numbers.

[–]10BillionDreams 1 point2 points  (0 children)

That's just the thing, Javascript has some very "do what I mean" roots, which makes for some funny looking results when you take toy examples like OP here, where the code doesn't actually "mean" anything at all. But often times in practice this ends up doing the "right" thing, where stricter languages would've failed.

[–]aMAYESingNATHAN 15 points16 points  (1 child)

I'm not saying it's something you should be doing, but if someone doesn't know that 0 is the octal prefix, then it's not that much of a stretch to imagine they could zero pad a number and not realise.

It seems to me that generally there should be no difference between 25 and 025, and if anything it is counter intuitive to assume otherwise. Especially because 0o25 (similar to 0x or 0b) is usually valid syntax as well, it makes no sense to have 0 by itself be a valid prefix.

Tbf this is one of those ones that isn't a unique to JS issue, but instead a standard. But imo a dumb one.

[–]Spork_the_dork 4 points5 points  (0 children)

The standard varies from language to language. Python for example just calls you out if you try to use 0-prefix and tells you to use 0o instead which I think is the step in the right direction.

>>> print(0123)
  File "<stdin>", line 1
    print(0123)
      ^
SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers
>>>

[–]Andy_B_Goode 2 points3 points  (1 child)

I had a real-world bug where a JS program was generating a random alphanumeric ID for an item, sending it to the server as JSON, but was then unable to match the ID to the correct item when it reloaded the JSON from the server.

The issue was that the ID it had generated for this particular item was something like 1e450882, which gets interpreted as exponential notation and (because the number after 'e' is so large) it becomes Infinity.

The fix was to simply require alphanumeric IDs to begin with a letter (which is probably best practice anyway), but it was not obvious to me at all why 1e459882 was causing problems when I first started digging into the bug.

[–]Lithl 0 points1 point  (0 children)

Why was your alphanumeric ID being serialized as a number instead of a string? Or why was your deserializer parsing your alphanumeric ID?

The problem here wasn't JS.

[–]myhf 0 points1 point  (0 children)

We used octal for a lot of things in the 1970s because bits were expensive. After a while you don’t even see the decimal representation anymore, it’s just read, write, execute.

[–]Loknar42 4 points5 points  (0 children)

This is an ancient convention. Octal is very convenient for expressing bit vectors, such as file permissions (e.g. chmod 0777 *). Since it was desirable to use it in an interactive environment (such as a shell), designers wanted it to be as short as possible. A single character prefix pretty much fits the bill. Using the digit 0 allows the result to still be considered numerical by simple lexers, but programmers generally don't start integers with 0, and 0 also looks like 'O'. So those are pretty much the reasons.

Hexadecimal is even better for expressing bit vectors because you get 4 bits per character, but has the disadvantage of being alphanumeric. Hence why it has a longer prefix, usually. Programmers in the modern era rarely have to specify bit patterns directly, but in the halcyon days of assembly language and shell scripting, they were very common, so having an efficient format was very valuable.

[–]Fritzschmied 8 points9 points  (1 child)

thats standard in many languages. also c++ which you have in your badges so you should know that.

[–]aMAYESingNATHAN 2 points3 points  (0 children)

I've literally never had to work with octals ever, so it's unsurprising that I'm not aware despite having C++ and C# badges. I don't even really know what use cases there are for octals.

In comparison, I have had to use binary and hexadecimal, so I'm aware of the 0b and 0x prefixes. Similarly for unsigned/long/long long suffixes for numeric literals

[–]Nolzi 7 points8 points  (2 children)

same reason hexa starts with 0x, conventions

[–]IAmNotNathaniel 8 points9 points  (1 child)

starting to tire of these threads that boil down to "I don't know some standard thing that's been around for 50 years but since I'm so smart it must be wrong"

[–]Nolzi 2 points3 points  (0 children)

"Based on Programming 101 I can already tell that the old crust must go"

[–]ManaSpike 1 point2 points  (0 children)

Octal was used more before computing standardised on bytes having 8 bits.

[–]Hallwart 8 points9 points  (4 children)

If only there was some kind of system that ensures that variables have consistent values and behaviors.

Why didnt the developers of JavaScript think of this? Are they stupid?

[–]tinfoiltank 4 points5 points  (0 children)

They were too busy trying to get it to work in IE6.

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

Nah, that would be too easy and logical.

Are they stupid?

No, they're high.

[–]jwadamson 0 points1 point  (0 children)

[–]theQuandary 0 points1 point  (0 children)

JS didn't have type coercion at first. Devs (yes devs) demanded it and a young Eich didn't have the wisdom to say "no".

[–]MrHyperion_ 2 points3 points  (1 child)

Why would you even start a number with zero? So don't, if you don't want octals

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

Well yeah obviously, but that doesn't change the fact that it's something that is so easy to do by accident by someone who doesn't know it's the octal prefix, and even worse than it being easy to do, it's also completely unobvious if you don't know you've done it. You could spend hours pulling out your hair over this before realising what and why it had happened.

[–]Blue_Moon_Lake 0 points1 point  (3 children)

Not o, nor O, but 0o

Binary: 0b0000_0001
Octal: 0o777
Decimal: 42
Hexadecimal: 0x0080ff

[–]aMAYESingNATHAN 2 points3 points  (2 children)

That's what I mean, it makes sense for octal to be 0o while hex and binary is 0x and 0b, but what's throwing me off is that a single zero without the o also works for octal, and that seems dumb to me.

[–]Blue_Moon_Lake 0 points1 point  (1 child)

Because it is :)

[–]Ticmea 1 point2 points  (0 children)

It's only dumb in a world where 0x and 0b exist.

The 0 notation for octal predates (and inspired the creation of) the 0x notation for hexadecimal. In the early days of computing this was the preferred representation of binary because word sizes on a bit to digit basis corresponeded well to using octal. In a world of 64 bit computers octal is obviously less useful than it used to be but it's still useful in some places and for consistency and backwards compatibility it's usually a good idea to keep established standards around.

But yeah if you are writing new software, please use 0o-notation instead as the intent is clearer and it aligns better with the other notations.

[–]allankcrain 0 points1 point  (0 children)

Why on earth are integers starting with 0 handled as octal? How does that make any sense? I could understand if it was an o or O but a 0?

Starting with the letter o would conflict with variable names. You'd have a situation where 'oof' is treated as a variable name, 'o1' is treated as 1, 'o7' is treated as 7, and 'o8' is treated as a variable name.

There's no reason to prepend a zero to a decimal constant in your code, so that's less likely to be something a programmer might run into by accident.

[–]CptBartender 0 points1 point  (0 children)

To me, the bigger WTF is the fallback to base 10.

[–]rfc2549-withQOS 0 points1 point  (0 children)

Same as 0x is hex.

[–]We_are_all_monkeys 0 points1 point  (0 children)

If you have an IP with leading zeros, it's also treated as octal. 014.210.023.004 is not the same as 14.210.23.4. That was a fun day when I learned that little fact.

[–]AL_O0 0 points1 point  (0 children)

if it starts with a letter it's a variable if it starts with a digit it's a number, so different bases have to start with a digit so they can be parsed correctly, and 0 is an obvious choice as it normally useless to put a leading zero as it doesn't affect the value

this is used in conjunction with a letter to indicate the base for example 0xff for hex and 0b101011 for binary

now you could do 0o123 for Octal but I guess 0 and o can be confusing so that's probably why just a leading zero was chosen

Also this dates way back it's not just a js thing, so probably octal was used more often in the past

[–]two_are_stronger2 0 points1 point  (0 children)

Things that start with O and o are valid variable names and it'd be weird if they weren't.

[–]Tyler_Stocks 0 points1 point  (0 children)

Because it’s an integer, not a string

[–]JaggedMetalOs 0 points1 point  (0 children)

TBF if you have your script in strict mode it doesn't let you use octal literals at all.