views:

105

answers:

5

I have a struct:

struct s
{
    UINT_PTR B_ID;
};
s d;
d.B_ID=0x1;

That works fine, but I want d.B_ID to be constant. I tried to use (const) but it didn't work. So after I put a value to d.B_ID, then I want make it a constant.

Any ideas?


EDIT

ok i don't want the whole struct a constant.
when i set timer and use the b.B_ID as an idea for the timer.
in the switch(wparam) { case b.B_ID // error: B_ID must be constant .... break; } so that is why i need it to be a constant

+2  A: 

Variable modifiers are fixed at compile time for each variable. You may have to explain the context of what you are trying to do, but perhaps this will suit your needs?

struct s
{
  int* const B_ID;
};

int main (void) {
  int n = 5;
  s d = {&n};
  int* value = d.B_ID; // ok
  //  d.B_ID = &n; // error
  return 0;
}

Since you are using C++ I would recommend:

class s {
public:
    int* const B_ID;

    s (int* id) :
    B_ID (id) {
    }
};

void main (void) {
   int n = 5;
   s my_s_variable = s(&n);

   int* value = my_s_variable.B_ID; // ok
   //my_s_variable.B_ID = &n; // error
   return 0;
}

Ramiz Toma: well i need way to do it using the s.B_ID=something

In C/C++ type modifiers (like const) are declared at run time for a given type and cannot be changed at run time. This means that if a variable is declared const it can never be assigned to using the assignment operator. It will only be assigned a value when it is constructed.

This is not a problem however because you can always get around this by proper design.

If you say you need to use assignment, I assume that this is because you create the struct before you know what the value of the variable will be. If this is the case then you simply need to move the struct declaration till after you know the value.

For example

s d; //variable declaration

//calculate B_ID
//...
int* n = 5;
//...


d.B_ID = &n;

This will not work, because if you want b.D_ID to be 'un assignable' it will always be so. You will need to refactor your code similarly to:

//calculate B_ID
//...
int* n = 5;
//...


s d (&n);
//good
Akusete
I tried the first one. it gave me an error that says can't set value for B_ID
Ramiz Toma
the second one didn't work too many errors
Ramiz Toma
@Ramiz Toma: I just gave a rough example of the concept... I've fixed it now to compile for you.
Akusete
well i need way to do it using the s.B_ID=something
Ramiz Toma
That is logically not possible. Either you want a static member variable, or you dont. You cannot change the member variables properties at run time. Post the code where you use the function and we can show you how to refactor it to use the approach given above.
Akusete
+3  A: 
struct s
{
   s() : B_ID(0){}
   UINT_PTR const B_ID;
};
int main(){
   s d;
   d.B_ID=0x1;  // error
}

EDIT: Sorry, here is the updated code snippet in C++

struct s
{
   s(UINT_PTR const &val) : B_ID(val){}
   UINT_PTR const B_ID;
};
int main(){
   s d(1);
   d.B_ID=0x1;  // error
}
Chubsdad
What is this supposed to show?
Shaihi
Looks perfect to me. From this the original questioner should be able to easily extract alternatives. The fact that chubsdad choose 0 instead of 1 is irrelevant.
Martin York
@Martin: it is better now that it has been fixed.
Jonathan Leffler
it still doesnt' work
Ramiz Toma
Error 2 error C2064: term does not evaluate to a function taking 1 arguments
Ramiz Toma
@Ramiz: do you have the updated `struct s` declaration?
Michael Burr
yes....................
Ramiz Toma
+1  A: 

You can't do that - ie. it is not possible to selectively make a single member of a struct const. One option is to 'constify' the entire struct:

s d;
d.B_ID=0x1;
const s cs = s; // when using this B_ID won't be modifiable - but nor would any other members

Or you could set it at construction:

struct s
{
    s(UINT_PTR const p): B_ID(p) {}
    UINT_PTR const B_ID;
};    
s d(0xabcdef);
Peter
Does your second example contradict your first statement?
Jonathan Leffler
yes, it does - but still the second example is the right way to do it.
Tobias Langner
well i got an error using the second oneerror 2 error C2064: term does not evaluate to a function taking 1 arguments
Ramiz Toma
Not really, but maybe I didn't explain clearly - it is not possible to have a mutable structure and change the members, then later on make only one member of it const. If it's const it has to be set at construction.
Peter
A: 

Another way would be a getter and a one time setter

class s
{
private:
   bool m_initialized;
   UINT_PTR m_value;
public:
   s() : m_initialized(false), m_value(NULL) {}
   s(UINT_PTR value) : m_initialized(true), m_value(value) {}

   //no need for copy / assignment operators - the default works

   inline UINT_PTR GetValue() const { return m_value; } //getter

   bool SetValue(UINT_PTR value) //works only one time
   {
       if (m_initialized)
       {
          m_value = value;
          m_initialized=true;
          return true;
       }
       else
       {
          return false;
       }
   }

   inline bool IsInitialized() const { return m_initialized; }
};
Tobias Langner
+3  A: 

In C++ language the case label must be built from an Integral Constant Expression (ICE). ICE is what the compiler implies under the term "constant" in your error message. A non-static member of a class cannot be used in an ICE. It is not possible to do literally what you are trying to do. I.e. it is not possible to use a struct member in a case label.

Forget about switch/case in this context. Use ordinary if branching instead of switch statement.

AndreyT