locked
Is there a way to create dynamic variable names? RRS feed

  • Question

  • I'd like to be able to create a set of variable names IF condition x==true

    say the variable's base name is "computer". I'm going to run code that checks a database. The first entry that satisfies x, will be assigned a variable named "computer1", the second entry that satisfies x will be named "computer2" and so on.

    I already know how to do it by saving the entry row numbers as integers as reference numbers, I just wanted to know if there was another way to do it.

    Friday, January 15, 2016 5:38 PM

Answers

  • I'd like to be able to create a set of variable names IF condition x==true

    say the variable's base name is "computer". I'm going to run code that checks a database. The first entry that satisfies x, will be assigned a variable named "computer1", the second entry that satisfies x will be named "computer2" and so on.

    It's not at all clear to me exactly how and where you intend to use these "variable names".

    I trust that you know that variable names exist in source code, but not in compiled object
    or linked executable code. (Except as part of data used by the debugger, etc.) It's therefore
    meaningless to try and construct or use variable names at run time as they are gone by then,
    variable names in your source code having been "consumed" by the build.

    You can associate strings with functions or data at runtime, but that is different from
    creating and using "variable names". e.g. - function pointer tables

    You need to clarify what you are trying to do with the different names. Assuming that you
    manage to construct a "name" at run time based on a database value, what do you expect/intend
    to do with that name?

    Your last code example seems convoluted and bug-riddled. Examples:

    int PRINT_with_name(char* name, T& val)
    {
    	char pc[10] = "computer";
    	pc[8] = '1';
    	name = pc;
    	
    

    "name" is a local char pointer variable whose contents are passed on the stack to this
    function. pc is a local variable which also exists only until the function exits.
    When you assign pc to name you are copying the address of pc into the local temp pointer
    variable "name". You subsequently do nothing with either "name" or "pc".

    The char array at the address pointed to by the caller of this function is not altered
    in any way by your function.

    int PRINT_with_name(char* name, T& val)
    {
    ...
    	int k(name) = 1;
    	return k(name);
    }
    

    What *exactly* were you expecting these two lines to do? As I commented in a prior post.
    your macro:

    #define k(x) x

    means that the preprocessor will substitute:

    int name = 1;
    return name;

    Since this conflicts with the use of "name" in the arguments, a compile error can be
    expected. However even if an error didn't occur, of what use is there in returning an int?
    How does that help to construct "variable names"?

    - Wayne

    Saturday, January 16, 2016 11:46 PM
  • If you don't need backing storage of the variable to be the same as some other declared variable, then you can simply use a std::map<std::string,int>

    std::map<std::string,int> variables;
    variables["computer1"] = 111;
    variables["computer2"] = 222;
    

    If you do need it to be the same storage as some other variable then that's possible, but with a little more work.  Like if you need to be able to reference int computer1;  with syntax like variable["computer1"] this is doable with a little extra setup.  I can show you how...just ask.

    Monday, January 18, 2016 3:19 PM

All replies

  • The preprocessor can stringize a macro argument using the stringizing operator.

    #define FOO(x) BAR(x,#x)

    Then FOO(hello) translates to BAR(hello,"hello")

    This is enough of a tool to make what you want happen with a little cleverness.

    #include <iostream>
    #include <string>
    
    template <typename T>
    void PRINT_with_name( T& val, const char* name )
    {
    	std::cout << "The value of " << name << " is " << std::to_string( val ) << std::endl;
    }
    
    #define PRINT(x) PRINT_with_name(x,#x)
    
    int main()
    {
    	int x = 5;
    	int y = 10;
    	PRINT( x );
    	PRINT( y );
    }

    Output:

    The value of x is 5
    The value of y is 10

    Friday, January 15, 2016 6:52 PM
  • or may be simply use an int variable , on your condition increment the value and print it

          int i=0;
    for(int i=0;i<10;i++)
    {
    cout<<"Computer "<<i<<std::endl;
    }

    Thanks


    Rupesh Shukla

    Friday, January 15, 2016 10:16 PM
  • Okay could I get another hint without giving away the answer; this is not working lol

    #define k(x) x
    template <typename T>
    int PRINT_with_name(char* name, T& val)
    {

    char pc[10] = "computer";
    pc[8] = '1';
    name = pc;
    int k(name) = 1;
    return k(name);
    }
    #define PRINT(x) PRINT_with_name(#x,x)

    ----------------

    I thought k(name) would return the value of variable name and be assigned an int =1.

     Why this didn't happen? it works fine when I try to cout << k(name);


    • Edited by -B-M- Saturday, January 16, 2016 3:52 PM
    Saturday, January 16, 2016 3:46 PM
  • this is not working

    #define k(x) x
    template <typename T>
    int PRINT_with_name(char* name, T& val)
    {

    char pc[10] = "computer";
    pc[8] = '1';
    name = pc;
    int k(name) = 1;
    return k(name);
    }


    Did that even compile without errors?

    The macro means that the line:

    int k(name) = 1;

    will become

    int name = 1;

    after preprocessing.

    But one of the arguments to the function is already called "name" and its type is char*
    so you are trying to redefine a formal parameter of the function. I would expect a compile
    error from that.

    - Wayne

    Saturday, January 16, 2016 10:25 PM
  • I'd like to be able to create a set of variable names IF condition x==true

    say the variable's base name is "computer". I'm going to run code that checks a database. The first entry that satisfies x, will be assigned a variable named "computer1", the second entry that satisfies x will be named "computer2" and so on.

    It's not at all clear to me exactly how and where you intend to use these "variable names".

    I trust that you know that variable names exist in source code, but not in compiled object
    or linked executable code. (Except as part of data used by the debugger, etc.) It's therefore
    meaningless to try and construct or use variable names at run time as they are gone by then,
    variable names in your source code having been "consumed" by the build.

    You can associate strings with functions or data at runtime, but that is different from
    creating and using "variable names". e.g. - function pointer tables

    You need to clarify what you are trying to do with the different names. Assuming that you
    manage to construct a "name" at run time based on a database value, what do you expect/intend
    to do with that name?

    Your last code example seems convoluted and bug-riddled. Examples:

    int PRINT_with_name(char* name, T& val)
    {
    	char pc[10] = "computer";
    	pc[8] = '1';
    	name = pc;
    	
    

    "name" is a local char pointer variable whose contents are passed on the stack to this
    function. pc is a local variable which also exists only until the function exits.
    When you assign pc to name you are copying the address of pc into the local temp pointer
    variable "name". You subsequently do nothing with either "name" or "pc".

    The char array at the address pointed to by the caller of this function is not altered
    in any way by your function.

    int PRINT_with_name(char* name, T& val)
    {
    ...
    	int k(name) = 1;
    	return k(name);
    }
    

    What *exactly* were you expecting these two lines to do? As I commented in a prior post.
    your macro:

    #define k(x) x

    means that the preprocessor will substitute:

    int name = 1;
    return name;

    Since this conflicts with the use of "name" in the arguments, a compile error can be
    expected. However even if an error didn't occur, of what use is there in returning an int?
    How does that help to construct "variable names"?

    - Wayne

    Saturday, January 16, 2016 11:46 PM
  • If you don't need backing storage of the variable to be the same as some other declared variable, then you can simply use a std::map<std::string,int>

    std::map<std::string,int> variables;
    variables["computer1"] = 111;
    variables["computer2"] = 222;
    

    If you do need it to be the same storage as some other variable then that's possible, but with a little more work.  Like if you need to be able to reference int computer1;  with syntax like variable["computer1"] this is doable with a little extra setup.  I can show you how...just ask.

    Monday, January 18, 2016 3:19 PM
  • I'd like to be able to create a set of variable names IF condition x==true
    say the variable's base name is "computer". I'm going to run code that checks a database. The first entry that satisfies x, will be assigned a variable named "computer1", the second entry that satisfies x will be named "computer2" and so on.

    It sounds to me as though you just need a collection rather than
    individual variables.

    Dave

    Monday, January 18, 2016 3:42 PM