Home AMX User Forum AMX General Discussion

Just another odd issue?

I changed a value of a constant from 64 to 128 and then when I compiled I got this error:
ERROR: E:\******************************VAV_ControlByWeb.axi(181): C10219: Array [CCBW_EMAIL_STR] must have an initializer if bounds are not specified  

referring to this variable:
VOLATILE CHAR cCBW_Email_Str[CBW_NUM_EMAILs * CBW_LEN_EMAILs];

These are the constants:
INTEGER CBW_NUM_EMAILs    = 6;
INTEGER CBW_LEN_EMAILs    = 128;
Now if I change the 128 to any other number, 127, 129, 64, 300 I don't get the error but as soon as I change it back to 128 the error comes back. Not a big deal, just another one of those things that make you go WTF!

Comments

  • Joe HebertJoe Hebert Posts: 2,159
    Each of these pairs cause the same error (NUM x LEN = 768):
    INTEGER CBW_NUM_EMAILs    = 4;
    INTEGER CBW_LEN_EMAILs    = 192;
    
    INTEGER CBW_NUM_EMAILs    = 8;
    INTEGER CBW_LEN_EMAILs    = 96;
    
    INTEGER CBW_NUM_EMAILs    = 12;
    INTEGER CBW_LEN_EMAILs    = 64;
    
    INTEGER CBW_NUM_EMAILs    = 16;
    INTEGER CBW_LEN_EMAILs    = 48;
    
    INTEGER CBW_NUM_EMAILs    = 24;
    INTEGER CBW_LEN_EMAILs    = 32;
    

    However, these work fine:
    INTEGER CBW_NUM_EMAILs    = 2;
    INTEGER CBW_LEN_EMAILs    = 384;
    
    INTEGER CBW_NUM_EMAILs    = 1;
    INTEGER CBW_LEN_EMAILs    = 768;
    
    


    That's messed up.
  • viningvining Posts: 4,368
    Yep, things that just make you scratch your head and say WTF!
  • ericmedleyericmedley Posts: 4,177
    I poked around on this for a while. fascinating. First I have never even tried to put an operator in a variable declaration before. That seemed like a bit of woo to me that caused me to fear risking the anger of the firmware gods. but anyway - it does work and so there you are.

    But, to the point, I then thought it had to do with some kind of fussiness with the fact that 127 and 128 are obvious points of interest if the under-the-hood dimensional size parameter might be a signed integer. (128 being equal to -127) I then tried several permutations around the signed integer turn around points at different nodes but they seem to work fine. Reversing the order behaved the same way. Oddly enough setting both values to 128 fails but having one be 127 and 128 works fine.

    So, it's clearly some issue with a signed integer as it does have nodes where it works and doesn't.

    I guess it's something I probably wouldn't do anyway since in a lot of development environments you can't get away with such frippery. But it is fascinating to watch.
  • viningvining Posts: 4,368
    ericmedley wrote: »
    I poked around on this for a while. fascinating. First I have never even tried to put an operator in a variable declaration before. That seemed like a bit of woo to me that caused me to fear risking the anger of the firmware gods. but anyway - it does work and so there you are.

    .
    Have you ever tried evaluations or using operators in a function call as a passed parameter?
    fnFB_DoSend_CHNL(iUI_Indx,9,nPower == 1);
    fnFB_DoSend_CHNL(iUI_Indx,27,nPower == 0);
    fnFB_DoSend_CHNL(iUI_Indx,28,nPower == 1);
    

    function:
    DEFINE_FUNCTION fnFB_DoSend_CHNL(INTEGER iUI_Indx,INTEGER iChannel,INTEGER iCHState)
    
         {
         STACK_VAR INTEGER n;
         STACK_VAR INTEGER nTPCount; 
         STACK_VAR INTEGER nLoopStart; 
    
         if(iUI_Indx)
          {
          nTPCount = iUI_Indx;
          nLoopStart = iUI_Indx;
          }
         else
          {
          nTPCount = sSBS.sPlayer.nNum_UIs;
          nLoopStart = 1;
          }
         //fnDevMod_DEBUG("'DoSend_CHNL: Running FB! :DEBUG<',ITOA(__LINE__),'>'",4);
         for(n = nLoopStart; n <= nTPCount; n++)
              {
          if(nUI_ActiveArry[n] == sSBS.sPlayer.nInstance)
               {
               SWITCH(nUI_TypeArry[n])
                {
                CASE UI_TYPE_iPHONE:
                CASE UI_TYPE_iTOUCH:
                CASE UI_TYPE_iPAD:
                CASE UI_TYPE_G4:
                CASE UI_TYPE_R4:
                CASE UI_TYPE_MIO_DMS:
                CASE UI_TYPE_G3:
                CASE UI_TYPE_METKP:
                CASE UI_TYPE_VIRTUAL:
                CASE UI_TYPE_UNKNOWN://leave this SWITCHin in CASE we choose to limit number of channels
                 {               //to specific types of devices (no online or comms status for keypads, etc)
                 SWITCH(iCHState)
                      {
                      CASE CH_OFF://0
                       {
                       OFF[dvUI_SBSArry[n],iChannel];
                       }
                      CASE CH_ON://1
                       {
                       ON[dvUI_SBSArry[n],iChannel];
                       }
                      CASE CH_PULSE://2
                       {
                       PULSE[dvUI_SBSArry[n],iChannel];
                       }
                      CASE CH_TOGGLE://3
                       {
                       [dvUI_SBSArry[n],iChannel] = (![dvUI_SBSArry[n],iChannel]);
                       }
                      }
                 }
                }
               }
          }
    
         RETURN;
         }
    

  • ericmedleyericmedley Posts: 4,177
    vining wrote: »
    Have you ever tried evaluations or using operators in a function call as a passed parameter?
    fnFB_DoSend_CHNL(iUI_Indx,9,nPower == 1);
    fnFB_DoSend_CHNL(iUI_Indx,27,nPower == 0);
    fnFB_DoSend_CHNL(iUI_Indx,28,nPower == 1);
    

    function:
    DEFINE_FUNCTION fnFB_DoSend_CHNL(INTEGER iUI_Indx,INTEGER iChannel,INTEGER iCHState)
    
    {
    STACK_VAR INTEGER n;
    STACK_VAR INTEGER nTPCount;
    STACK_VAR INTEGER nLoopStart;
    
    if(iUI_Indx)
    {
    nTPCount = iUI_Indx;
    nLoopStart = iUI_Indx;
    }
    else
    {
    nTPCount = sSBS.sPlayer.nNum_UIs;
    nLoopStart = 1;
    }
    //fnDevMod_DEBUG("'DoSend_CHNL: Running FB! :DEBUG<',ITOA(__LINE__),'>'",4);
    for(n = nLoopStart; n <= nTPCount; n++)
    {
    if(nUI_ActiveArry[n] == sSBS.sPlayer.nInstance)
    {
    SWITCH(nUI_TypeArry[n])
    {
    CASE UI_TYPE_iPHONE:
    CASE UI_TYPE_iTOUCH:
    CASE UI_TYPE_iPAD:
    CASE UI_TYPE_G4:
    CASE UI_TYPE_R4:
    CASE UI_TYPE_MIO_DMS:
    CASE UI_TYPE_G3:
    CASE UI_TYPE_METKP:
    CASE UI_TYPE_VIRTUAL:
    CASE UI_TYPE_UNKNOWN://leave this SWITCHin in CASE we choose to limit number of channels
    { //to specific types of devices (no online or comms status for keypads, etc)
    SWITCH(iCHState)
    {
    CASE CH_OFF://0
    {
    OFF[dvUI_SBSArry[n],iChannel];
    }
    CASE CH_ON://1
    {
    ON[dvUI_SBSArry[n],iChannel];
    }
    CASE CH_PULSE://2
    {
    PULSE[dvUI_SBSArry[n],iChannel];
    }
    CASE CH_TOGGLE://3
    {
    [dvUI_SBSArry[n],iChannel] = (![dvUI_SBSArry[n],iChannel]);
    }
    }
    }
    }
    }
    }
    
    RETURN;
    }
    

    Yes. I've never had ant issue with them. But, there is the weird thing that happens in Netlinx that is maddening.

    If you pass a global variable into a function, and then do something to change the declared variable value in the function, that change gets propagated backwards into your global. I've gotten into the habit of putting the value(s) I need to go into the funtciton into stack_vars, passing them into the function, and then even in the function, taking the passed in values and storing them in stack_vars there to process. It drives me crazy.
  • ericmedley wrote: »

    Yes. I've never had ant issue with them. But, there is the weird thing that happens in Netlinx that is maddening.

    If you pass a global variable into a function, and then do something to change the declared variable value in the function, that change gets propagated backwards into your global. I've gotten into the habit of putting the value(s) I need to go into the funtciton into stack_vars, passing them into the function, and then even in the function, taking the passed in values and storing them in stack_vars there to process. It drives me crazy.

    That it updates the global isn't the "weird" part, that works similarly to pass by reference in other common/standard languages. What is "weird" (I prefer interesting) is that AMX Functions are more "pass/return by <working> copy", than a true pass by reference implementation... I can understand why the compiler writers did it (simpler), but it isn't really standard with regards to async behaviour.
Sign In or Register to comment.