const pointer to a const string

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • hschew00
    New Member
    • Aug 2009
    • 12

    #1

    const pointer to a const string

    I have the following:

    Code:
    float var_1, var_2;
    const char* const UNIT1 = "kPa";
    const char* const UNIT2 = "ft";
    
    struct PARAMETER 
    {
    	float*   value;
    	int      par_type;
    	int      max_index;
    	float    init;
    	float    min;
    	float    max;
    	float    step;
    	char*    unit;
    };
    
    const struct PARAMETER params[] = 
    {
     {
    	&var_1,              //*value
    	0,                   //type
    	0,                   //max_index
    	0,                   //init
    	0,                   //min
    	10,                  //max
    	1,                   //step
    	"kPa"                //unit
     },
     {
    	&var_2,              //*value
    	0,                   //type
    	0,                   //max_index
    	0,                   //init
    	0,                   //min
    	10,                  //max
    	1,                   //step
    	"ft"                 //unit
     }
    };
    The above compiled fine, however, if I replace the instance params' unit to the following:
    Code:
    const struct PARAMETER params[] = 
    {
     {
    	&var_1,              //*value
    	0,                   //type
    	0,                   //max_index
    	0,                   //init
    	0,                   //min
    	10,                  //max
    	1,                   //step
    	UNIT1                //unit
     },
     {
    	&var_2,              //*value
    	0,                   //type
    	0,                   //max_index
    	0,                   //init
    	0,                   //min
    	10,                  //max
    	1,                   //step
    	UNIT2                //unit
     }
    };
    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?
  • donbock
    Recognized Expert Top Contributor
    • Mar 2008
    • 2427

    #2
    Your example that works actually might not quite work. The part that doesn't quite work is equivalent to
    Code:
    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:
    Code:
    struct PARAMETER  
    {
        ...
        const char* unit; 
    };
    This change incidentally solves the problem you asked about regarding using UNIT1 or UNIT2 in the initializer.

    Comment

    • hschew00
      New Member
      • Aug 2009
      • 12

      #3
      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.

      Comment

      • hschew00
        New Member
        • Aug 2009
        • 12

        #4
        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;
        or
        const char* unit;
        within PARAMETER STRUCTURE. Beat me.

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          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.
          Code:
          #define UNIT1 "kPa"
          #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.

          Comment

          • hschew00
            New Member
            • Aug 2009
            • 12

            #6
            Don,
            Using the suggested #define is fine, as indicated by my first example, or the equivalent passing the constant address
            Code:
            const char  UNIT1[] = "kPa";
            const char  UNIT2[] = "ft";
            I just don't understand why I can't pass the constant pointer to a constant to the structure.

            Comment

            • Banfa
              Recognized Expert Expert
              • Feb 2006
              • 9067

              #7
              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.

              Comment

              Working...