0

I'm going through an exercise book on C and came across the statement

printf("%c", "\n");

Which when run in a console still works but displays the "$" symbol.

Why did this statement not crash the console like

printf("%s", '\n'); 

does?

Lewis Briffa
  • 557
  • 3
  • 6
  • 15
  • 3
    This is [undefined behaviour](http://stackoverflow.com/a/4105123/1505939) , anything may happen – M.M Jun 08 '16 at 22:22
  • 1
    Undefined behavior does not necessarily always cause a crash. Sometimes you get random output instead. Sometimes other undefined things happen. – Bill Lynch Jun 08 '16 at 22:22

5 Answers5

3

a double quoted string like that produces a value of a pointer to char (aka char*), while the single quote produce a value that's a character (using the ASCII value of whats in the quotes. On some compilers you can stack multiple characters into the single quotes.

printf("%c", *("\n") );

would print your linefeed, as the * operator would dereference the pointer

( You could probably do *"\n" , I just tend to be conservative in writing expressions)

printf("%s", '\n'); 

crashes because %s expects a pointer, and a linefeed cast into a pointer is pointing off in the weeds and most likely causes an invalid memory access

infixed
  • 1,155
  • 7
  • 15
3

It will invoke undefined behavior by passing data having wrong type. It just happened not to crash.

In some implementation, the pointer converted from the string literal is passed as an argument. Unlike %s, which will interpret the argument as pointer and go to read thete, %c will just take the argument as a number and print it, so it has less chance to crash.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
2

Because %s expects a NUL terminated string where %c only wants a char. The string will read past the end of your buffer (the single char) looking for that NUL and quite likely cause a memory exception. Or not - hence undefined behavior.

Michael Dorgan
  • 12,453
  • 3
  • 31
  • 61
  • The first example tries to interpret a pointer as a `char`. The second tries to treat an `int` as a pointer... but the problem isn't the missing null, it's dereferencing an invalid pointer and trying to print what it points to. – Dmitri Jun 08 '16 at 22:31
0

Only the latter statement asked the implementation to dereference an invalid pointer. An invalid value will typically show as garbage. But most possible memory location values are inaccessible and attempting to access them will cause a crash on modern operating systems.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
0

%s prints until it reaches a '\0' because \n has no escape it will read into memory. "%c" only needs a char

Mikes3ds
  • 592
  • 5
  • 12
  • in this case where it starts reading is probably more toxic (as in causing an exception) than what it would be reading, absent the exception. On simpler memory models (like 16 bit DOS), most likely that %s `printf` would just dump some garbage based on the contents of memory starting at address 0x000a – infixed Jun 08 '16 at 22:33