Is printf(c); is a valid syntax (where c is a string literal)?

377 views Asked by At

I came to this question and see this line

printf(&c[i]);  

I want to know that, is this a valid syntax ? Printing a string/string literal without format specifier %s does't cause undefined behavior or constraint violation ?
And if this is a valid syntax then in what purpose it is used ?

I compiled this code

#include <stdio.h>

int main()
{
    char *c = "Hello World";

    printf(c);
    printf("\n\n");
    printf(&c[0]);

    return 0;
}  

and it compiles without giving any warning/error with output

Hello World

Hello World
5

There are 5 answers

0
dreamlax On

It's unwise (particularly if said string came from a user), but it's not illegal.

The clause in question would be section 7.19.6.1, paragraph 3 (emphasis mine):

The format shall be a multibyte character sequence, beginning and ending in its initial shift state. The format is composed of zero or more directives: ordinary multibyte characters (not %), which are copied unchanged to the output stream; and conversion specifications, each of which results in fetching zero or more subsequent arguments, converting them, if applicable, according to the corresponding conversion specifier, and then writing the result to the output stream.

You should either use fputs(c); or fprintf("%s", c); to make sure your string isn't accidentally interpreted to contain directives.

0
Zhongzhi On

It's allowed but it's risky. Consider some function as below.

void foo(const char* s) {
    printf(s);
}

It might generate a core if something like %s is in the input argument.

0
JoelFan On

It works but is not recommended. Suppose you had

char *c = "We have a 30%sale!";

Then your printf statements would be accessing garbage memory trying to resolve the %s.

2
Kerrek SB On

Your use of printf is a prime example of unsafe code: The correctness of your program cannot be determined from the source code (and specifically the type system) alone; correctness depends on values rather than types. The fact that such code is possible makes C an "unsafe language". Example:

void f(char const * p)
{
    printf("%s", p);      // this is safe!

    printf(p);            // correct if the string contains no format specifiers;
                          // undefined behaviour otherwise
}

To repeat: The correctness of your program depends on its runtime characteristics, and cannot be guaranteed statically.

You should never write such code!

1
Alexander Perechnev On

It works because c is a pointer to start of string (in other words it is pointer to first sign of your string). c[0] lets you a char W. And & let's you pointer to this char. The construction such you used in code just gets the value by pointer and immediately returns the pointer of this value. For example c[i] is equal to *(c+i).

Why it works? Because printf() function receives a pointer to string as argument. And it prints all sign starting from pointer up to '\0' sign.

Please learn more about pointers in C language and how C-arrays and C-string are implemented.