By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,963 Members | 1,260 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,963 IT Pros & Developers. It's quick & easy.

const pointer to a const string

P: 12
I have the following:

Expand|Select|Wrap|Line Numbers
  1. float var_1, var_2;
  2. const char* const UNIT1 = "kPa";
  3. const char* const UNIT2 = "ft";
  5. struct PARAMETER 
  6. {
  7.     float*   value;
  8.     int      par_type;
  9.     int      max_index;
  10.     float    init;
  11.     float    min;
  12.     float    max;
  13.     float    step;
  14.     char*    unit;
  15. };
  17. const struct PARAMETER params[] = 
  18. {
  19.  {
  20.     &var_1,              //*value
  21.     0,                   //type
  22.     0,                   //max_index
  23.     0,                   //init
  24.     0,                   //min
  25.     10,                  //max
  26.     1,                   //step
  27.     "kPa"                //unit
  28.  },
  29.  {
  30.     &var_2,              //*value
  31.     0,                   //type
  32.     0,                   //max_index
  33.     0,                   //init
  34.     0,                   //min
  35.     10,                  //max
  36.     1,                   //step
  37.     "ft"                 //unit
  38.  }
  39. };
The above compiled fine, however, if I replace the instance params' unit to the following:
Expand|Select|Wrap|Line Numbers
  1. const struct PARAMETER params[] = 
  2. {
  3.  {
  4.     &var_1,              //*value
  5.     0,                   //type
  6.     0,                   //max_index
  7.     0,                   //init
  8.     0,                   //min
  9.     10,                  //max
  10.     1,                   //step
  11.     UNIT1                //unit
  12.  },
  13.  {
  14.     &var_2,              //*value
  15.     0,                   //type
  16.     0,                   //max_index
  17.     0,                   //init
  18.     0,                   //min
  19.     10,                  //max
  20.     1,                   //step
  21.     UNIT2                //unit
  22.  }
  23. };
the above was compiled with error:
error C2099: initializer is not a constant

What is the proper way to pass constant char pointer to a constant in this case?
Sep 10 '10 #1
Share this Question
Share on Google+
6 Replies

Expert 100+
P: 2,396
Your example that works actually might not quite work. The part that doesn't quite work is equivalent to
Expand|Select|Wrap|Line Numbers
  1. char *unit = "kPa";
The problem here is that compilers are allowed to store string literals in read-only memory. (Whether they do or not is implementation-dependent.) Variable unit is not a pointer-to-const, so your program could try to modify the literal string. If the literal string were indeed stored in read-only memory and if your run-time environment has an MMU then this would provoke a run-time error.

You could protect yourself from this possibility by changing the definition of the PARAMETER structure to:
Expand|Select|Wrap|Line Numbers
  1. struct PARAMETER  
  2. {
  3.     ...
  4.     const char* unit; 
  5. };
This change incidentally solves the problem you asked about regarding using UNIT1 or UNIT2 in the initializer.
Sep 10 '10 #2

P: 12
Don, at first I followed the same logic as you stated, however, the Visual C compiler could not compile it successfully, same as the Keil compiler that I used. The first example can be compiled by both, and the memory buffer on the hardware confirmed the intended data stored at the right location. Try it on the VC6 and you know what I meant.
Sep 11 '10 #3

P: 12
One more thing with the suggestion that you proposed, not only it did not compiled with UNIT1 and UNIT2 as initializers, it did compiled correctly with string literals as initializers "kPa" and "ft", and the compiled hex file from Keil compiler is the same for both
char* unit;
const char* unit;
Sep 11 '10 #4

Expert 100+
P: 2,396
Make sure UNIT1 and UNIT2 are defined before params[]. C doesn't support forward references.

If that doesn't work, try &UNIT1[0] in the initializer instead of UNIT1.

As a last resort change UNIT1 and UNIT2 into macros; then you should be able to use them in the initializer.
Expand|Select|Wrap|Line Numbers
  1. #define UNIT1 "kPa"
  2. #define UNIT2 "ft"
At least one of these strategies should allow you to define the units field as a const char *. If not, post the error messages you get.

the compiled hex file from Keil compiler is the same for both char* unit; or const char* unit; within PARAMETER structure.
That's to be expected. The difference you get by making units a pointer-to-const is that you get a compiler error if you try to change the string pointed to by units.
Sep 11 '10 #5

P: 12
Using the suggested #define is fine, as indicated by my first example, or the equivalent passing the constant address
Expand|Select|Wrap|Line Numbers
  1. const char  UNIT1[] = "kPa";
  2. const char  UNIT2[] = "ft";
I just don't understand why I can't pass the constant pointer to a constant to the structure.
Sep 13 '10 #6

Expert Mod 5K+
P: 8,916
I assume you are compiling as C and not C++.

The problem is that initialisers need to be constant values but in C variables declared as const are not constant values, they are just variables that you can not change by assignment so they can not be used in initialiser lists or for declaring array sizes.

In C++ variables declared const are constant values and can be used in this situation.
Sep 13 '10 #7

Post your reply

Sign in to post your reply or Sign up for a free account.