#if_not_defined ?
vining
Posts: 4,368
In a module I am pesently working on I decided to use the #DEFINE, #IF_NOT_DEFINED and #END_IF to control my diagnostic SEND_STRING 0, messages instead of using a Virtual channel in a IF statement to determine whether or not to bombard the terminal with all the diagnostic messages all the time. My thinking was that these line of codes, IF's conditions and SEND_STRING's don't need to be there 99.999% of the time the code is running but only when developing or troubleshooting. So I figured I'd use the #DEFINE DEBUG and put the #IF_NOT_DEFINED DEBUG in front of all diagnostics based code and send_strings with obviously the #END_IF after and when wanting to use the DEBUG ) I would uncomment the line #DEFINE DEBUG and re-compile. That way all that debug stuff isn't compiled and running with the actual working code.
That seems to work fine in the INCLUDE .axi but how does that work in the associated module when thats compiled before the MAIN .axs file does. I tried to use a different #DEFINE in the module with an #INCLUDE there after to the .axi file but it doesn't appear to like #IF_NOT_DEFINED XXXXXX and #END_IF with in a different set of #IF_NOT_DEFINED YYYYYY and #END_IF.
Now with just the #DEFINED DEBUG in the .axi that seems to halt the send_string 0 from the module but I can't imagine how. It's already compiled when I do the MAIN.axs so it has no way of knowing if its "DEFINED". So is it working like a typical if condition? I'm trying to eliminate thos section from compiling for normal operation and only use it when I need to. I also just want to control this abilitiy from the .axi so I don't have to include the source code of the module. Actually that can't work because the module would have to be compile for it to take affect. So I guess the simplest thing to do is just put a #DEFINE DEBUG in the module as well.
For my own edification is it possible to put these #IF_NOT_DEFINED statement with in other #IF_NOT_DEFINED statements. Can the compiler figure it out and works its way outward from the middle set?
That seems to work fine in the INCLUDE .axi but how does that work in the associated module when thats compiled before the MAIN .axs file does. I tried to use a different #DEFINE in the module with an #INCLUDE there after to the .axi file but it doesn't appear to like #IF_NOT_DEFINED XXXXXX and #END_IF with in a different set of #IF_NOT_DEFINED YYYYYY and #END_IF.
Now with just the #DEFINED DEBUG in the .axi that seems to halt the send_string 0 from the module but I can't imagine how. It's already compiled when I do the MAIN.axs so it has no way of knowing if its "DEFINED". So is it working like a typical if condition? I'm trying to eliminate thos section from compiling for normal operation and only use it when I need to. I also just want to control this abilitiy from the .axi so I don't have to include the source code of the module. Actually that can't work because the module would have to be compile for it to take affect. So I guess the simplest thing to do is just put a #DEFINE DEBUG in the module as well.
For my own edification is it possible to put these #IF_NOT_DEFINED statement with in other #IF_NOT_DEFINED statements. Can the compiler figure it out and works its way outward from the middle set?
0
Comments
If you want a given define or flag or constant value or similar to be available in all modules, put it with all of its friends in a special include and include it at the beginning of every source file. I call mine "iBuildConstants.axi".
I didn't follow your description of your code; could you please post an example?
Here's a piece of the code:
But I think you are complicating matters.
If your goal is to be able to turn on/off your debug send_string 0's, you could just define a virtual device and a debug flag for each element you want to debug. Then you could just do a SEND_Command to the virtual device "DEBUG=1" or "DEBUG=0" from telnet.
For example...
Then.... [/QUOTE]
Now all you would need to do is the following from telnet...
SEND_COMMAND vdvVAV_NP_DEBUG,"'DEBUG=1'"
or
SEND_COMMAND vdvVAV_NP_DEBUG,"'DEBUG=0'"
No new recompiles/downloads needed
#DEFINE and the associated #IF's that go with it are pre-compiler statements. They are evaluated before the code is compiled. If used in an #INCLUDE (which is also a pre-compiler operation), the compiler session is going to have no way to distinguish one from the other if they are similarly named. If you really must use them, give your #DEFINEs a unique name for every component - so your main code can use DEBUG, but your modules can call it MODULE_1_DEBUG, or something like that.
if (dvVirtual,255])
{
send_string 0, stuff .......
}
I would set the channel when I wanted to see the debug. The problem is, although not a big problem, is that the debug code is always running for no reason the only difference is whether or nor we send it to view in terminal. My thinking is why even compile it in the code for normal day to day operation. If you need it re-compile with the #DEFINE whatever un-commented, debug, and when finished, re-compile with it commented out effectively removing all debug code from running in the normal ay to day operation. There's no need for it running when no one is viewing terminal and the send_string 0, is only part of the running debug code.
The way I was previously doing this was just around the send_string itself and didn't include the rest of the debug code. Which was sort of me being simple/stupid.
I'll wrestle with which method is the best all around one to use but your (Dave & KennyP) preferences are well noted.
The #IF_NOT_DEFINE or #IF_DEFINE can they be used with in each other?
like:
#IF_NOT_DEFINED X
some code stuff.
#IF_NOT_DEFINED Y
some code stuff.
#END_IF
some other code stuff.
#END_IF
can the compiler handle this.
Although on the size and type of systems I've been working on, shutting down to re-compile isn't an issue, the systems alot of you guys work on, shutting down to re-compile might not be a viable option or an option at all in order to see what's going on.
I discovered a while ago by experimentation with an NXC-ME260 that send_string 0 slugs the processor massively. I don't know why and I don't know if it does the same on an NI. Nevertheless I write my code to maximise the debug information but then to be able to reduce it to little or nothing as the code matures.
When I first write new code, I litter it profusely with verbose calls to a debug function - most functions will send a list of all arguments, for example. (If every module did this all the time the result would not be nice.)
The debug function decides whether to send_string it according to the state of a variable (one for each module).
As the code matures and the debug stream begins to get tedious, I comment out all the (a) trivial (reliable) stuff I never want to see again - but leave it there just in case I hit a problem.
Major functions (c) that I always want to see in the debug stream eg button pushes or significant system state changes get left in the code, and always get sent when the debug variable is on.
In between (b) is a large class of debug call that I only want to see when I'm debugging that module, and that I don't want to fatten the code and the processor load in other circumstances. These I put inside an "#if_defined FullDebug" bracket, with the "#define FullDebug" right up at the top of the module in clear view.
The last thing I do before leaving a site is to search for "#define FullDebug" and comment them all out and set the default values of all the debug variables to False, then recompile and reload a minimal size / minimal load program.
I'm very careful to ensure that no non-debug code creeps into the debug bracket as this would be Not Good.
I include this at the beginning of all files as shown below:
Then in all areas of code that related to feed back (send_string 0, stuff) I do this:
This works real well but requires re-compiling associated files if modules and then the main.axs but changes to debug operation are only made in the dubug include .axi which I place references to which files are effected and other notes as needed. I just put this together today so it's not complete.
Plus I think the simpler [dvVirtual,channel] or global VAR flagging method may be more beneficial as I can enable or disable feedback during runtime which so far isn't a big deal to me now but because it may be in the future I want to pick the right path for the long haul not just immediate satisfaction. Although that's good to!
I thought I was in favor of the flagging method but I like this one too!
That siad, this is my (latest) standard procedure for debugging:
I create a vritual device and use channel one as a debug flag. I have a regular debug message function that will send debug messages if the channel is set on, and the function identifies the originating master (or device, if it's a module). I call this function liberally throughout my program; it provides any kind of status I like, and does nothing at all if my debug channel is not on. Out of sheer laziness and ease of typing, I will usually have a variable that folows the channel state, and I can test against that instead of the channel. The vritual device also has a command handler that I can use to query my system if telnetted in from a remote site. I can turn the channel on and off via telnet, and it doesn't depend on me being at a location that has Studio installed for debugging; I can also walk another tech through the procedure if I am driving or otherwise not in a position to do it myself.
After looking up the meaning of the word "niggardly", I agree. As long as the evaluation of the "IF" condition stays with in the processor itself the time to evaluate, say a thousand send_string related IFs probably wouldn't take a millisecond to complete.
Unfortunately being anal in conjunction with my OCD makes me reluctant to undo something I've done after writing it. My systems are comparatively small and the compiled code is around 1 meg compiled so there's plenty of space available. Part of the anal OCD thing requires me to finish something before I throw it out and do something diferent, which makes no sense at all but that's the way I am.
I stated previously the benefits of channel or var flagging with "IF" conditions far out weigh the minuscule gains of the #DEFINE/#IF_NOT_DEFINE method and that will be the method I will implement in all my code. I just had to take the #DEFINE/#IF_NOT_DEFINE method to a level of completeness before moving on.
Hopefully in time I will grasp some of the other things you are doing and implement something similar as well.