-2

This works and produces bbcd as I'd expect.

#include <stdio.h>

int main(void) {
    char string[] = "abcd";

    string[0] = string[1];

    printf("%s\n", string);
}

This is a bus error.

#include <stdio.h>

int main(void) {
    char *string = "abcd";

    string[0] = string[1];

    printf("%s\n", string);
}

Why?

Valgrind says:

==9909== Process terminating with default action of signal 10 (SIGBUS)
==9909==  Non-existent physical address at address 0x100000FA2
==9909==    at 0x100000F65: main (test.c:6)
Schwern
  • 153,029
  • 25
  • 195
  • 336
  • 1
    `abcd` is a constant. You can do `char string[5] = "abcd";`instead. – Support Ukraine Nov 04 '16 at 07:47
  • 1
    Please use search before asking questions. – 2501 Nov 04 '16 at 07:48
  • 1
    `char string[] = "abcd";` declares an array and initialises it with `{ 'a', 'b', 'c', 'd', '\0' }`. `char *string = "abcd";` declares a pointer to a `char` and initialises it with a pointer to the beginning of the **constant string** `"abcd"`. You can change the array you declared, but modifying a constant string leads to undefined behaviour. –  Nov 04 '16 at 07:49
  • @2501 ["char bus error"](http://stackoverflow.com/search?q=char+bus+error) turns up a lot of unrelated things. Thanks for pointing out the dup. – Schwern Nov 04 '16 at 07:50
  • @PaulRooney can you show some reference to your comment? – Sourav Ghosh Nov 04 '16 at 07:51
  • @2501 C has oh so many fascinating traps and pitfalls. – Schwern Nov 04 '16 at 07:52
  • @PaulRooney Type of a string literal is `char[*]`. – 2501 Nov 04 '16 at 07:52
  • @PaulRooney I tried `cc -Weverything -pedantic -std=c99 test.c` and no warnings. – Schwern Nov 04 '16 at 07:52
  • @Schwern Yes. The moto is: don't assume anything. – 2501 Nov 04 '16 at 07:53
  • @Schwern Add the flag `-Wwrite-strings` (if clang supports it). – 2501 Nov 04 '16 at 07:54
  • @2501 Of course! `-Wall` isn't all so why would `-Weverything` be everything? \*sigh\* It didn't catch it. I got a warning about my lack of `const` which might have at least been a hint. "*initializing 'char *' with an expression of type 'const char [5]' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]*" (I only sat down and properly learned C last winter) – Schwern Nov 04 '16 at 07:57
  • @Schwern You shouldn't ignore that warning. – 2501 Nov 04 '16 at 07:59
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/127353/discussion-between-schwern-and-2501). – Schwern Nov 04 '16 at 08:02

1 Answers1

0

Because in the second case, you're trying to modify a string literal which invokes undefined behavior.

To elaborate, in the second case, string[0] is the first element of the string literal, and any assignment to that is an attempt to modify the value held by that element.

Quoting C11, chapter §6.4.5, "String literals"

[...] If the program attempts to modify such an array, the behavior is undefined.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261