Tiago Oliveira
Tiago Oliveira

Reputation: 158

Does C add '\0' when you pass a literal string as an argument in a function?

For instance, if I write:

void function(char *k){ printf("%s",k);}

and call it like this:

function("hello");

does the code translate that string to: "hello\0" ? Or I'm the one who has to add it?

Upvotes: 3

Views: 1709

Answers (4)

Nicholas Pipitone
Nicholas Pipitone

Reputation: 4182

In C (And C++), when you do const char* mystr = "Hello";, the compiler will generate the following in (read-only) RAM:

0x7fff2fe0: 'H'
0x7fff2fe1: 'e'
0x7fff2fe2: 'l'
0x7fff2fe3: 'l'
0x7fff2fe4: 'o'
0x7fff2fe5: '\0'

Then, the compiler will replace

const char* mystr = "Hello";

with

const char* mystr = 0x7fff2fe0;

For your usage, your code will turn into

function(0x7fff2fe0)

Simple as that.

On a compiler level, all string literals have type const char[N], where the char array is an array that contains all of the written characters, followed by a \0. The char[N] has a length N that is 1 + the length of the string you write (char[6] for "Hello"). More information can be found in the here, where they also use the string "Hello" as an example. Thus, sizeof("Hello") == 6, and "Hello"[5] == '\0' (Yes, "Hello"[5] is legal, remember, "Hello" has type const char[6]). We see this information exemplified in the following:

printf("%d\n", sizeof("Hello")); // 6
const char[] str = "Hello"; // Casts from const char[6] to const char[6]
                            // Resulting in a copy of all 6 bytes
printf("%d\n", sizeof(str)); // 6
const char* str2 = "Hello"; // Casts from const char[6] to const char*
printf("%d\n", sizeof(str2)); // 4 on a 32bit system, 8 on a 64bit system

Do note, when casting to a pointer, that you get some pointer e.g. 0x7fff2fe0 to an array of characters that is not modifiable - attempting to modify the data pointed at 0x7fff2fe0 or 0x7fff2fe5 is explicitly undefined behavior. This status is commonly represented with const; by writing const, the compiler will correctly complain if you try to edit it.

As an additional note, by writing

char[] myarr = "Hello";

You will create a duplicate stack-allocated character array named myarr, and that array may be modified. myarr will indeed still contain \0 and have a size of 6 chars, in particular, myarr will have type char[6], with sizeof(myarr) == 6.

Upvotes: 5

0___________
0___________

Reputation: 67855

String literals are not passed to the functions only the pointer to the first character. The referenced object will have all the chars + terminating zero.

Upvotes: 1

AnT stands with Russia
AnT stands with Russia

Reputation: 320719

A string literal already includes a terminating \0 by itself, regardless of what you do with that literal. "hello" is always a char [6] array of h, e, l, l, o and \0, by definition. So, the fact that you "pass it to a function" is completely inconsequential here.

There's no need to add anything.

Upvotes: 4

rmoro
rmoro

Reputation: 393

From the C11 Standard Section 6.4.5 String Literals, Paragraph 6 (p. 71):

In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. 78) The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence

Upvotes: 4

Related Questions