Home AMX User Forum NetLinx Studio

Problem assigning a string constant to a variable

Hi all, I've stumbled across an assignment problem and I'm wondering if anybody could explain what's happening.

Include file:
DEFINE_CONSTANT
char SWITCH_PORT_1[] = '1.3.6.1.4.1.1.2.3.4.5.0';

Main file:
DEFINE_VARIABLE
CHAR sSwitchOID[]   = SWITCH_PORT_1;

This results in a compiler warning:
WARNING: Main.axs(75): C10571: Converting type [string] to [CHAR]

I can't for the life of me figure out why it wants to cast that to a CHAR. Naturally it works fine if I copy-and-paste the string in place of the constant. Does anybody have any insights into this? Thanks. :)

Comments

  • ericmedleyericmedley Posts: 4,177
    DEFINE_CONSTANT
    char SWITCH_PORT_1[25] = { '1.3.6.1.4.1.1.2.3.4.5.0'} ;
    


    Try this.
  • tomktomk Posts: 24
    Hi Eric. I'm afraid that makes no difference. I've also tried setting an array length on the variable, which doesn't help either.
  • try this I don't have a controller available right now to test.

    DEFINE_CONSTANT
    Char CONST_TMP [] = '1.2.3.4.5.6.7.8.9.0';

    DEFINE_VARIABLE
    VOLATILE Char TmpStr [50];

    DEFINE_START
    {
    TmpStr = "CONST_TMP";
    }

    I will try in the am when I get into the office.
  • a_riot42a_riot42 Posts: 1,624
    This compiles without issue on my machine when putting the two terms in the same main axs file. I would suggest you have something else going on here.
    Paul
  • tomktomk Posts: 24
    Thanks all for the suggestions.

    jdonachiue: Setting it in DEFINE_START works fine like you suggest. That will be my Plan B. I'm still curious to know what's at work here though!

    a_riot42: I tried creating a fresh workspace with only the following in Main.axs:
    PROGRAM_NAME='Main'
    
    DEFINE_CONSTANT
    char SWITCH_PORT_1[] = '1.3.6.1.4.1.1.2.3.4.5.0';
    
    DEFINE_VARIABLE
    char sSwitchOID[]   = SWITCH_PORT_1;
    
    DEFINE_START
    send_string 0,"'Switch OID: ',sSwitchOID";
    

    I still get the warning "WARNING: C:\Code\TestWorkspace\Main.axs(8): C10571: Converting type [string] to [CHAR]".

    Did you do anything differently?
  • a_riot42a_riot42 Posts: 1,624
    I copied/pasted this:
    DEFINE_CONSTANT
    char SWITCH_PORT_1[] = '1.3.6.1.4.1.1.2.3.4.5.0';
    
    DEFINE_VARIABLE
    char sSwitchOID[]   = SWITCH_PORT_1;
    
    DEFINE_START
    send_string 0,"'Switch OID: ',sSwitchOID";
    

    into my current project and it compiles with no errors.
    Paul
  • tomktomk Posts: 24
    Well then, that is fascinating. I checked WebUpdate - I am running the latest version of Netlinx Studio. Obviously this isn't a showstopper issue but if anybody can explain what's going on I'll find that very satisfying. :)

    Thanks for testing, Paul!
  • DHawthorneDHawthorne Posts: 4,584
    The problem is in your variable declaration, not the constant declaration. You are initializing it with a constant, but it's a declared constant, and doesn't exist until runtime, so it's really a read-only variable. You can't initialize a variable with a variable, and that is what it's tantamount to doing. You can initialize with an actual string constant, or load it in startup.
  • a_riot42a_riot42 Posts: 1,624
    Sorry I just realized that I am getting a warning, but no errors. I thought you were getting an error which I tried to duplicate, but realize after reading your post again, you are just getting a warning not an error. I don't write Netlinx code in this manner, so I don't see these warnings very often. You can get some pretty funky errors and warnings if you start to color outside the lines in Netlinx. I prefer to stay inside them for the sake of my own sanity.
    Paul
  • tomktomk Posts: 24
    DHawthorne wrote: »
    You are initializing it with a constant, but it's a declared constant, and doesn't exist until runtime, so it's really a read-only variable. You can't initialize a variable with a variable, and that is what it's tantamount to doing.

    Ah, that is the kind of insight I was looking for. Thanks. :) I had been assuming that global variables were initialised at runtime from a precompiled data segment like in PC binaries. Good stuff.
  • a_riot42a_riot42 Posts: 1,624
    DHawthorne wrote: »
    You are initializing it with a constant, but it's a declared constant, and doesn't exist until runtime, so it's really a read-only variable.

    Not sure what you mean. It exists at compile time, since its hard coded in the file. Its read only, but that doesn't mean you can't assign it to a variable.

    It looks to me like he forgot the second set of brackets. This compiles with no warnings.

    char sSwitchOID[][] = SWITCH_PORT_1;
    Paul
  • tomktomk Posts: 24
    So here's an interesting thing.

    If I follow Paul's suggestion I get no warning. But when I run this code on an NI-700...
    PROGRAM_NAME='Main'
    
    DEFINE_CONSTANT
    char SWITCH_PORT_1[] = '1.3.6.1.4.1.1.2.3.4.5.0';
    tl1 = 1;
    
    DEFINE_VARIABLE
    char sSwitchOID[][]   = SWITCH_PORT_1;
    long timearray[1];
    
    DEFINE_START
    timearray[1] = 1000;
    timeline_create(tl1, timearray, 1, TIMELINE_RELATIVE, TIMELINE_REPEAT);
    
    DEFINE_EVENT
    TIMELINE_EVENT [tl1] {
        send_string 0,"'Switch OID: ',sSwitchOID";
        send_string 0,"'String len: ',itoa(length_string(sSwitchOID))";
    }
    
    ...I get the following in my diagnostic log:
    Line     42 (10:42:27)::  String len: 1
    Line     43 (10:42:28)::  Switch OID:
    
    If I add a constant declaration:
    constant char sSwitchOID[][]   = SWITCH_PORT_1;
    
    Then I still get no warnings, but now diagnostic output like this:
    Line      1 (10:45:06)::  Switch OID: 1.3.6.1.4.1.1.2.3.4.5.0
    Line      2 (10:45:06)::  String len: 23
    
    "Forgot" is too kind. :) To me it now looks like a declaration of a two-dimensional array being initialised by a one-dimensional array. I must be misunderstanding the syntax somehow. Could anyone please explain what the double brackets is doing?
  • a_riot42a_riot42 Posts: 1,624
    I got rid of the warning for you, now you expect me it to make it work too? Sheesh.

    You're coloring outside the lines, so you're on your own here. Once embarked on a Netlinx gremlin finding exercise, you never know what'll turn up. What gets printed if you add a third set of brackets?

    char sSwitchOID[][][] = SWITCH_PORT_1;

    Paul
  • tomktomk Posts: 24
    I can report that without the "constant" modifier I can have up to 503 pairs of square brackets and still get the same behaviour as above: variable not set correctly, reported length 1.

    With the "constant" modifier I can have up to 502 pairs of square brackets and get the same behaviour: variable set correctly, reported length 23.

    If I exceed either of those limits I get an error:
    ERROR: C:\Code\TestWorkspace\Main.axs(8): C10201: Syntax error; Illegal or Invalid syntax in code
    
    This happens to be slightly over 1024 bytes in a line so it I suspect it is a parser error than anything else.

    Obviously this example is ridiculous, but arbitrary behaviour from the compiler makes me unhappy. Perhaps somewhere there is a note "The behaviour when initialising a global variable with a constant defined under DEFINE_CONSTANT is undefined", though I haven't spotted it in any documentation. I think I'll just make that a personal rule and move on.

    Thanks all for the suggestions!
  • a_riot42a_riot42 Posts: 1,624
    tomk wrote: »
    I can report that without the "constant" modifier I can have up to 503 pairs of square brackets and still get the same behaviour as above: variable not set correctly, reported length 1.

    With the "constant" modifier I can have up to 502 pairs of square brackets and get the same behaviour: variable set correctly, reported length 23.

    Interesting. I wonder how much memory a 503 dimensional array takes up? I shudder to think.
    tomk wrote: »
    Obviously this example is ridiculous, but arbitrary behaviour from the compiler makes me unhappy.

    Then you are bound to be an unhappy Netlinx programmer. This is the AMX jungle not the clean clinical labs of Sun Microsystems. Be grateful that at least the compiler gave you a warning! Often you just get runtime weirdness with nothing to indicate where to even begin looking. Remember segmentation faults where your OS would simply crash when you ran your program? No fancy shmancy null pointer messages with the accompanying stack trace here. You need to practise defensive programming in Netlinx, which means don't do anything unless you know for sure it will work in the real world. If you start to assume the compiler works correctly or the documentation is always correct, you will end up with a lot of gray hair!
    Paul
  • tomktomk Posts: 24
    a_riot42 wrote: »
    If you start to assume the compiler works correctly or the documentation is always correct, you will end up with a lot of gray hair!

    Haha okay, useful advice. Thanks. :)
Sign In or Register to comment.