348

Zero is always zero, so it doesn't matter. But in a recent discussion with a friend he said that octal literals are almost unused today. Then it dawned upon me that actually almost all integer literals in my code are octal, namely 0.

Is 0 an octal literal according to the C++ grammar? What does the standard say?

The only real use I'm aware of is for unix file permissions.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • 7
    Is this the same for Java? – Philippe Aug 01 '11 at 11:57
  • 87
    +1 for asking an entirely irrelevant question and getting tons of upvotes :-) – Kerrek SB Aug 01 '11 at 18:28
  • 72
    I think the way to instant rep on SO is not a profound question, but a peculiar question whose answer would land you geek cred at the water cooler :) – Josh Aug 01 '11 at 18:39
  • @JoachimSauer are you really sure? –  Jul 21 '14 at 11:36
  • 18
    I'm almost tempted to post an answer that says "Yes, 0 is a decimal literal or an octal literal." – Keith Thompson Oct 30 '14 at 15:42
  • Reminds me of the http://en.wikipedia.org/wiki/Barber_paradox, because logically the compiler *must* do it one way or another, while in practice it doesn't matter at all. Funny anyway. :-) – Stéphane Gourichon Mar 19 '15 at 19:13
  • 6
    Terrific question :) I looked it up in the [Java Language Spec](http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html "Java Language Spec"), and in Java it is decimal. The spec even contains the following quote: *Note that octal numerals always consist of two or more digits; 0 is always considered to be a decimal numeral - not that it matters much in practice, for the numerals 0, 00, and 0x0 all represent exactly the same integer value.* – Tobias Ritzau Sep 05 '12 at 07:32

3 Answers3

310

Yes, 0 is an Octal literal in C++.

As per the C++ Standard:

2.14.2 Integer literals [lex.icon]

integer-literal:  
    decimal-literal integer-suffixopt  
    octal-literal integer-suffixopt  
    hexadecimal-literal integer-suffixopt  
decimal-literal:  
    nonzero-digit  
    decimal-literal digit  
octal-literal:  
    0                           <--------------------<Here>
    octal-literal octal-digit
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 41
    The other important point being that a _decimal-literal_ is a _nonzero-digit_ followed by zero or more _digit_ so there is no ambiguity. – CB Bailey Aug 01 '11 at 07:53
  • Not that anyone would notice if we'd change it to `octal-literal: 0 octal-digit*` and `decimal-literal: digit*`. And I bet there are compilers which implement it that way. – MSalters Aug 01 '11 at 08:27
  • 3
    @MSalters: With your version, you have to additionaly specify the preference: If _both_ `octal-literal` and `decimal-literal` are possible interpretations of the byte pattern, pick `octal-literal`. The official standard's wording doesn't have this problem. – Martin Sojka Aug 01 '11 at 08:46
  • 23
    @MSalters: You still couldn't have _decimal-literal_ as any number of digits, it would have to be a single zero or a non-zero digit followed by any digits otherwise _every_ octal literal could be interpreted as a decimal literal. I can see the compile error, now: `ERROR: 0 is ambiguous, could be octal zero or could be decimal zero. Consider using (1 - 1) to disambiguate`. – CB Bailey Aug 01 '11 at 09:25
  • The idea would be that your compiler didn't bother to distinguish them in the grammar, as both can occur at the same places. This is an example where a theoretical grammar ambiguity doesn't need to be resolved in practice. – MSalters Aug 01 '11 at 10:55
  • 1
    Now i'm curious about the rationale behind this decision. Say, in Java 0 is decimal, not octal. – Malcolm Aug 01 '11 at 11:07
  • 2
    @Malcolm: between the specification of C and the specification of Java quite some time passed and compilers/lexers/parsers became more refined. That might have influenced the decision. Also: It doesn't matter. – Joachim Sauer Aug 01 '11 at 12:10
  • 3
    @MSalters In your example, 0123 would match both octal-literal and decimal-literal, but would have different meanings either way. – fluffy Aug 01 '11 at 18:43
  • Just out of curiosity: given that octal numbers are only 0-7 (i.e. 8 possible numbers, or octal) why did they choose to make 0 an octal-literal given that they also use the numbers 8 and 9? (caveat: I could be a complete idiot when it comes to this stuff) – Don Rhummy Aug 03 '11 at 00:17
  • 1
    @Don: "given that they also use the numbers 8 and 9?"? – Lightness Races in Orbit Aug 08 '11 at 15:12
  • 1
    @Don: they chose to make an octal literal anything that begins with "0". So 0777 is octal. But they can't use the number 8 for the prefix, otherwise 8777 would be octal and how would you specify the "8777" number in decimal? – Andreas Bonini Nov 09 '11 at 17:01
  • 5
    @CharlesBailey - FTFY, with `1` still being octal and all ;P - `ERROR: 0 is ambiguous, could be octal zero or could be decimal zero. Consider using (8 - 8) to disambiguate` – twalberg Jun 18 '12 at 20:23
  • 1
    Anyway, 0 is an octal only as a lexical definition, that is, in our minds. Any compiler will translate it to one or more groups of 8 zero bits, making it effectively base 256. (unless it's compiling for a cpu that uses a word that's not multiple of 8, but are those still around?) – Petruza Apr 02 '19 at 13:24
47

Any integer value prefixed with 0 is an octal value. I.e.: 01 is octal 1, 010 is octal 10, which is decimal 8, and 0 is octal 0 (which is decimal, and any other, 0).

So yes, '0' is an octal.

That's plain English translation of the grammar snippet in @Als's answer :-)


An integer prefixed with 0x is not prefixed with 0. 0x is an explicitly different prefix. Apparently there are people who cannot make this distinction.

As per that same standard, if we continue:

 integer-literal:
     decimal-literal integer-suffixopt
     octal-literal integer-suffixopt
     hexadecimal-literal integer-suffixopt
 decimal-literal:
     nonzero-digit                       <<<---- That's the case of no prefix.
     decimal-literal digit-separatoropt digit
 octal-literal:
     0                                    <<<---- '0' prefix defined here.
     octal-literal digit-separatoropt octal-digit <<<---- No 'x' or 'X' is
                                                          allowed here.
 hexadecimal-literal:
     0x hexadecimal-digit                 <<<---- '0x' prefix defined here
     0X hexadecimal-digit                 <<<---- And here.
     hexadecimal-literal digit-separatoropt hexadecimal-digit
littleadv
  • 20,100
  • 2
  • 36
  • 50
  • 5
    "Any integer value starting with '0' is an octal value." Not true. Example: 0xA starts with '0' and is an integer value. – Nikolai Ruhe Mar 01 '13 at 11:05
  • 4
    `0x` is not a token. An integer literal starting with `0x` is a single token. – Keith Thompson Oct 30 '14 at 15:40
  • 1
    @KeithThompson sorry to burst your bubble, but you're wrong. *"A token is a string of one or more characters that is significant as a group."*. – littleadv Oct 30 '14 at 18:20
  • 6
    What source are you quoting for that definition? The word "token" is defined *syntactically* by the C (N1570 6.4) and C++ (C++11 2.7 [lex.token]) standards. `0x` does not qualify. (At least in C, it is a *preprocessing number* (N1570 6.4.8) if it's not part of a hexadecimal constant, but that's not a token.) – Keith Thompson Oct 30 '14 at 18:22
  • 2
    @KeithThompson I'm using the word "token", not the term "token" from the C standard. I described what "token" is when parsing a text based on grammar. I know it is hard to comprehend that there are differences in how people define words, but in Computer Sciences, the most accepted definition is *not* the one you refer to. – littleadv Oct 30 '14 at 18:28
  • 12
    We are discussing the syntax of integer constants/literals *as defined by the C and C++ standards*. How is the standards's definition of "token" not the most appropriate one to use in this context? Your insulting condescension is inappropriate. And if you think I'm a bully for pointing out something that I think is a technical error in your answer, I suggest you should reconsider the meaning of that word. (You never did answer my question about the source of your definition.) – Keith Thompson Oct 30 '14 at 18:39
  • 4
    If anybody's curious, the statement that "*A token is a string of one or more characters that is significant as a group.*" appears to be from [this Wikipedia article](http://en.wikipedia.org/wiki/Lexical_analysis#Token). – Keith Thompson Oct 30 '14 at 20:25
  • 2
    And if anybody thinks it is incorrect they're free to correct it. I do not understand your obsession though. – littleadv Oct 30 '14 at 23:53
-1

Apparently all integer literals starting with zero are in fact octal. This means that it includes 0 as well. This makes little difference since zero is zero. But not knowing this fact can hurt you.

I realized this when I was trying to write a program to convert binary numbers to decimal and hexidecimal output. Everytime that I was giving a number starting with zero I was getting the wrong output (For example, 012 = 10, not 12).

It's good to know this information so you don't make the same mistake.

Lee Louviere
  • 5,162
  • 30
  • 54
MCG
  • 81
  • 9
  • 7
    Integer literals starting with zero but without the 'x' after the zero. – luiscubal Aug 01 '11 at 16:32
  • Question is: Is 0 an octal literal according to the C++ grammar? Extra Comment is: I'm just curious what the standard says. This answers the question. If you're going to get technical about the answer, then let's get technical about the question. – Lee Louviere Aug 02 '11 at 14:57
  • 5
    An assertion "yes" without proof is not an answer, either. – Lightness Races in Orbit Aug 05 '11 at 01:01
  • @Xaade: The question is not about my existence. – Lightness Races in Orbit Aug 08 '11 at 15:11
  • 1
    By this logic, 09 is an octal number. – 0xc0de Aug 26 '13 at 08:44
  • @0xc0de Open VS 2012, create an example C++ project, assign 09 to an integer variable . You'll get the following error; Error 1 error C2041: illegal digit '8' for base '8' – MCG Sep 04 '13 at 13:26
  • @MCG: ???? That's what I am pointing out, forget about VS 2012 and please read definition of octal numbers. 09 is not an octal number and I am giving that as a proof that this logic of yours 'all integer literals starting with zero are in fact octal.' is incorrect. Your logic says 09 is an octal number but it is not. – 0xc0de Sep 04 '13 at 13:48
  • 1
    You are right, the way I tried to express is wrong. It should be; "By definition,if you are representing a decimal by with a leading zero in VS, it will interpret the number as octal". That explains the down votes – MCG Sep 04 '13 at 14:07
  • 3
    @0xc0de: No, `09` is not an octal number, because it's not a number at all; it doesn't match the syntax for any kind of integer literal. – Keith Thompson Aug 08 '14 at 17:31
  • 7
    I'm pretty confident that @0xc0de *knows* that `09` is not an octal number. What was said was, "*By this logic*, `09` is an octal number." The implication is that, since `09` is *not* an octal number, the logic must be wrong. – TRiG Oct 30 '14 at 15:37
  • @TRiG: And Keith is pointing out the fallacy in 0xc0de's comment. The answer (in the form in existence when 0xc0de commented, which is revision 2, the same one active today) makes no claims about things which are not integer literals, including the code snippet `09`. – Ben Voigt Sep 19 '19 at 14:21