printf("%lu \n", sizeof(*"327")); I always thought that size of a pointer was 8 bytes on a 64 bit system but this call keeps returning 1. Can someone provide an explanation?
Putting * before a string literal will dereference the literal (as string literal are array of characters and will decay to pointer to its first element in this context). The statement
printf("%zu \n", sizeof(*"327")); is equivalent to
printf("%zu \n", sizeof("327"[0])); "327"[0] will give the first element of the string literal "327", which is character '3'. Type of "327", after decay, is of char * and after dereferencing it will give a value of type char and ultimately sizeof(char) is 1.
'3' an integer constant. As per C standard an integer character constant has type int.int in C. Only in C++ is '3' (or 'm') of type char. Don't believe it? int main() { printf("%zu\n", sizeof 'm');}int in C'3' (i.e. a character literal). It is dereferencing a string literal (char*) to the first element which will be a char and hence a single byte (*(char*) = (char)). It just happens that the value of the dereferenced string literal is (char)'3' because that is the first character in the string.sizeof('3') has always been the same as sizeof(int). Likewise, sizeof(*"3") has always been the same as sizeof(char). As illogical as it may sound, a character literal is not of type char. In fact, all literals in C are at least the size of int. To get something of type char, you need an expression with something other than a literal in it.The statement:
printf("%lu \n", sizeof(*"327")); actually prints the size of a char, as using * dereferences the first character of string 327. Change it to:
char* str = "327"; printf("%zu \n", sizeof(str)); Note that we need to use %zu here, instead of %lu, because we are printing a size_t value.
The string literal is an anonymous, static array of chars, which decays to a pointer to its first character -- that is, a pointer value of type char *.
As a result expression like *"abc" is equivalent to *someArrayOfCharName, which in turn is equivalent to *&firstCharInArray which results in firstCharInArray. And sizeof(firstCharInArray) is sizeof(char) which is 1.
const. So it decays to a plain non-const char *. This is one of the things that makes C and C++ different.sizeof "abcd" is 5. Applying the dereference operator is a decay context of courseGood answer by haccks.
Also, the behaviour of your code is undefined, because you have used the wrong format specifier.
So, use %zu instead of %lu because sizeof() returns size_t and size_t is unsigned.
C11 Standard: §7.21.6.1: Paragraph 9:
If a conversion specification is invalid, the behavior is undefined.225) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
size_t is of smaller or equal size as unsigned long.size_t is, either it doesn't promote, or it promotes to signed int/unsigned int, so the only way you'll get an unsigned long passed to printf is if size_t already is an unsigned long. I don't see how you can say, then, that the behaviour is defined if size_t is anything else.size_t to be a typedef for unsigned long
sizeof(*"327")issizeof(char)since*dereferences the first char of your literal string. just trysizeof(char *)printf(and family) reference, because"%lu"is the wrong format forsizeofarguments.sizeofis no function that could be called.sizeofsizeof(&"327").