3

From code below

#include<stdio.h>
int main()
{
    char *s;
    s="cool man army";  //here LHS and RHS are same type
    printf("ptr= %zd, normal string= %zd",sizeof(s),sizeof("cool man army"));
    return 0;
}

s is char * type and "cool man army" is also char * then why are outputsptr= 8, normal string= 14 different?

Konrad Rudolph
  • 482,603
  • 120
  • 884
  • 1,141
beta_me me_beta
  • 836
  • 3
  • 11

4 Answers4

7

A string literal is actually an array, not a pointer. Section 6.4.5p6 of the C standard regarding string literals states:

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. The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence.

So when it is the operand of the sizeof operator, the usual decay to a pointer does not happen and you get back the size of the array in bytes.

The behavior of array decay into a pointer is documented in section 6.3.2.1p3:

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array oftype’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

dbush
  • 162,826
  • 18
  • 167
  • 209
  • I was wondering why "cool man army" showed behaviours like pointer, but its actually like an array, i got your point. – beta_me me_beta Feb 11 '20 at 18:05
  • @beta_meme_beta: You can read more about arrays decaying to a pointer in [this StackOverflow question](https://stackoverflow.com/questions/1461432/what-is-array-decaying). – Andreas Wenzel Feb 11 '20 at 18:14
0

First one is a chars pointer, the second not. You could see it with typeinfo header:

printf("%s %s", typeid(s).name(), typeid("cool man army").name());

And see something like that

Pc
A14_c

You could see that the second is an array of 14 chars.

dcariotti
  • 410
  • 1
  • 3
  • 10
0

First, your code don't compile in C++. You cannot drop const like that when building in c++ mode.

I think the mistake is here:

s="cool man army";  //here LHS and RHS are same type

They are not the same type. String literals are character array, and those decay into pointers.

The type of the string literal is char const[14]. In C++, you can create a reference to it:

auto const& ref_to_literal = "cool man army";
assert(sizeof(ref_to_literal) == sizeof("cool man army")); // True!
Guillaume Racicot
  • 32,627
  • 7
  • 60
  • 103
0

Since you tagged the question with both "C" and "C++", I will answer the question for both languages.

The statement

s = "cool man army";

where s is of type char * is only valid in C, not C++. In C++, the variable s must be of type const char *, because the string literal decays to that type. Only in C does the string literal decay to the type char *. However, in both languages, the string literal is read-only, even if it is not const in C.

On modern 64-bit platforms, pointers are normally 64-bit, that is why sizeof(s) is 8 bytes (which is equivalent to 64 bits). The string literal "cool man army" however is an array and not a pointer (and also does not decay to one when used with the sizeof operator). Therefore, sizeof("cool man army") is the actual length of the array (including the terminating null character), which is 14.

EDIT: Meanwhile, the C++ tag has been removed from the question. However, since it was not the OP who did that, I will not remove my comments about C++ from my answer.

Andreas Wenzel
  • 4,984
  • 2
  • 7
  • 24