Sizeof string literal
Asked Answered
P

2

61

The following code

#include <iostream>    
using namespace std;

int main()
{
    const char* const foo = "f";
    const char bar[] = "b";
    cout << "sizeof(string literal) = " << sizeof( "f" ) << endl;
    cout << "sizeof(const char* const) = " << sizeof( foo ) << endl;
    cout << "sizeof(const char[]) = " << sizeof( bar ) << endl;
}

outputs

sizeof(string literal) = 2
sizeof(const char* const) = 4
sizeof(const char[]) = 2

on a 32bit OS, compiled with GCC.

  1. Why does sizeof calculate the length of (the space needed for) the string literal ?
  2. Does the string literal have a different type (from char* or char[]) when given to sizeof ?
Phemia answered 8/9, 2009 at 5:47 Comment(0)
G
138
  1. sizeof("f") must return 2, one for the 'f' and one for the terminating '\0'.
  2. sizeof(foo) returns 4 on a 32-bit machine and 8 on a 64-bit machine because foo is a pointer.
  3. sizeof(bar) returns 2 because bar is an array of two characters, the 'b' and the terminating '\0'.

The string literal has the type 'array of size N of const char' where N includes the terminal null.

Remember, arrays do not decay to pointers when passed to sizeof.

Guardafui answered 8/9, 2009 at 5:56 Comment(6)
+1, but the type is actually 'array of N const characters' (const is not optional)Susie
@dribeas: yes; I was ignoring the qualifiers, but you are pedantically correct.Guardafui
@JonathanLeffler ... the best kind of correct, especially when it comes to programmingBarina
the fact that the comment about const appeared minutes after the answer puts a smile on my face.Callup
For 2., if memory serves, it's NOT guaranteed to be 4 or 8, according to the C standard. However the spirit is correct - it will be the sizeof(const char *), whatever that pointer size may be, and of course has no bearing on the actual length of the string. On some platforms/architectures/in some compilers (historically), pointer sizes and layouts changed depending on the type. This is why, for example, you must explicitly cast pointers to their expected types (if they differed) in variadic function calls since the cast could change the pointer value entirely.Placet
@AlexMarshall, I heard technically correct was the best kind of correct. But I think you're technically correct in this case. I'll update my a posterioris.Pulverize
O
14

sizeof returns the size in bytes of its operand. That should answer question number 1. ;) Also, a string literal is of type "array to n const char" when passed to sizeof.

Your test cases, one by one:

  • "f" is a string literal consisting of two characters, the character f and the terminating NUL.
  • foo is a pointer (edit: regardless of qualifiers), and pointers seem to be 4 bytes long on your system..
  • For bar the case is the same as "f".

Hope that helps.

Ockham answered 8/9, 2009 at 5:53 Comment(4)
Why is a char[] the same as a striong literal though? I'm not a C/C++ expert, but I thought that char[] and char* were interchangable?Occult
+1 on the general answer (and for speed :) A couple of precisions: foo IS a pointer (essentially qualifier does not apply) and in C++ the type is always "array of n const char" (constant-ness is not optional)Susie
@dribeas: right you are, const always applies. @Matthew: char* and char[] are only the same under certain circumstances, the sizeof operator is not one of them.Ockham
@Matthew: Nope, arrays and pointers are not interchangeable. An array can be passed whenever a pointer is expected, as it decays to a pointer. But as long as the type is an array, it is not the same as a pointer.Clueless

© 2022 - 2024 — McMap. All rights reserved.