Search code examples
coctal

char array initialization with octal constant


I saw a comment that said initialization of a char array with "\001" would put a nul as the first character. I have seen where \0 does set a nul.

The unedited comment:

char input[SIZE] = ""; is sufficient initialization. while ( '\001' == input[0]) doesn't do what you think it is doing if you have initialized input[SIZE] = "\001"; (which creates an empty-string with the nul-character as the 1st character.)

This program

#include <stdio.h>
#define SIZE 8
int main ( void) {
    char input[SIZE] = "\001";

    if ( '\001' == input[0]) {//also tried 1 == input[0]
        printf ( "octal 1\n\n");
    }
    else {
        printf ( "empty string\n");
    }
    return 0;
}

running on Linux, compiled with gcc, outputs:

octal 1

so the first character is 1 rather than '\0'.
Is this the standard behavior or just something with Linux and gcc? Why does it not set a nul?


Solution

  • Is this the standard behavior or just something with Linux and gcc? Why does it not set a nul?

    The behavior of the code you present is as required by the standard. In both string literals and integer character constants, octal escapes may contain one, two, or three digits, and the C standard specifies that

    Each octal [...] escape sequence is the longest sequence of characters that can constitute the escape sequence.

    (C2011, 6.4.4.4/7)

    In this context it is additionally relevant that \0 is an octal escape sequence, not a special, independent code for the null character. The wider context of the above quotation will make that clear.

    In the string literal "\001", the backslash is followed by three octal digits, and an octal escape can have three digits, therefore the escape sequence consists of the backslash and all three digits. The first character of the resulting string is the one with integer value 1.

    If for some reason you wanted a string literal consisting of a null character followed by the decimal digits 0 and 1, then you could either express the null with a full three-digit escape,

    "\00001"
    

    or split it up like so:

    "\0" "01"
    

    C will join adjacent string literals to produce the wanted result.