Is there a difference between these two declarations?

Hi all,

Is there a difference between these:

const char *str = "Hello";

const char str[] = "Hello";

? If so, what is the difference?

Thanks.

-- Roger

const char *str = "Hello";

A pointer to a string of characters. The memory could be allocated anywhere, including read-only memory, and the address is stored as the initialiser for this variable. Technically you can really only manipulate the pointer and not the text string.

const char str[] = "Hello";

An array of charaters that are initliased to the value of the string. Equivalent to initialising as ['H', 'e', 'l', 'l', 'o', '\0']. In this case the memory allocated will definitely be R/W and you can be expected to modify the string.

Is there a difference between these:

You can dump the object code that each produces to see the true differences. For the most part, the results will be the same. Both allocate and initialize some memory. The amount of memory is exactly the same.

marco_c:

const char str[] = "Hello";

An array of charaters that are initliased to the value of the string. Equivalent to initialising as ['H', 'e', 'l', 'l', 'o', '\0']. In this case the memory allocated will definitely be R/W and you can be expected to modify the string.

Not with the word "const" there you can't.

Let's do a little test shall we?

const char *str = "Hello";
const char str2[] = "Hello";
const char *str3 = "Hello";
const char str4[] = "Hello";

void setup ()
  {
  Serial.begin (115200);

  Serial.println ((unsigned int) str, HEX);
  Serial.println ((unsigned int) str2, HEX);
  Serial.println ((unsigned int) str3, HEX);
  Serial.println ((unsigned int) str4, HEX);
  }  // end of setup

void loop () { }

Output:

100   <-- str
10A   <-- str2
100   <-- str3
110   <-- str4

(Sorry, PaulS, for omitting the 1 from the first variable name.)

You can see that:

const char *str = "Hello";
const char *str3 = "Hello";

... point to the same memory location (0x100) since they are just pointers and they point to the same thing.

However str2 and str4 point to (occupy) different locations because you have asked for an array (not a pointer) and the variable happens to point to that array. So each time you ask for an array you get different memory locations. Because they are const you can't modify them, but if they weren't you could store stuff into those arrays (up to the size that was allocated, namely the size of the word "Hello" plus its terminating 0x00 byte.

Not with the word "const" there you can't.

Good point, missed that keyword.

Is the fact that the first and #3 point to the same memory location due to compiler optimization?

I would think that since they were declared separately, they would be distinct entities in memory even though they contain the same data, UNLESS the compiler is smart enough to see that they are the same?

Is the fact that the first and #3 point to the same memory location due to compiler optimization?

I would think that since they were declared separately, they would be distinct entities in memory even though they contain the same data, UNLESS the compiler is smart enough to see that they are the same?

Yes to both, sadly it wont put them in flash when there constants!.

Mark

I don't usually think of this as an "optimization", any more than when you write the expression x= x*3.0/2.0 the copiler pre-calculates the 3.0/2.0. It is more of an expected feature.

It is actually part of the C Standard. According to Harbison and Steele:
"Do not depend on all string constants being stored at different addresses. Standard C allows implementations to use the same storage for two strings that contain the same characters."

KeithRB:
I don't usually think of this as an "optimization", any more than when you write the expression x= x*3.0/2.0 the copiler pre-calculates the 3.0/2.0. It is more of an expected feature.

It is actually part of the C Standard. According to Harbison and Steele:
"Do not depend on all string constants being stored at different addresses. Standard C allows implementations to use the same storage for two strings that contain the same characters."

Yes, It is an OPTIMIZATION> Even if it is part of the standard it is still an optimization. In this case it is a memory optimization.

Yes, but it is optimization you can't turn off. 8^)

Krupski:
Is the fact that the first and #3 point to the same memory location due to compiler optimization?

I would think that since they were declared separately, they would be distinct entities in memory even though they contain the same data, UNLESS the compiler is smart enough to see that they are the same?

The pointers occupy distinct areas in memory. What they point to doesn't.

str2 and str4 in my example are not pointers, they are arrays. Hence they occupy different addresses.

This expanded sketch demonstrates that:

const char *str = "Hello";
const char str2[] = "Hello";
const char *str3 = "Hello";
const char str4[] = "Hello";

void setup ()
  {
  Serial.begin (115200);

  Serial.println ((unsigned int) str, HEX);
  Serial.println ((unsigned int) str2, HEX);
  Serial.println ((unsigned int) str3, HEX);
  Serial.println ((unsigned int) str4, HEX);
  
  Serial.println ("Addresses of variables:");

  Serial.println ((unsigned int) &str, HEX);
  Serial.println ((unsigned int) &str2, HEX);
  Serial.println ((unsigned int) &str3, HEX);
  Serial.println ((unsigned int) &str4, HEX);
  
  }  // end of setup

void loop () { }

Output:

118  <-- str
122  <-- str2
118  <-- str3
128  <-- str4
Addresses of variables:
11E  <-- address of str
122  <-- address of str2
120  <-- address of str3
128  <-- address of str4

Note that for the arrays (str2 and str4) the "pointer" is the variable.

For the pointers (str and str3) the variables are at unique addresses (0x11E and 0x120) but what they point to is at the same address, as the compiler has realized it can point them both to the string "Hello" (stored at 0x118).