fabric Posted April 11, 2013 Report Share Posted April 11, 2013 Grrr... It's happening more often now. I'm sure I've read about it here before but maybe it's time to table the issue again: I'm working on a large project, and I'm running LV2012 32 and 64 bit on Windows. I have an typedef enum inside a class. The enum happens to be the sole member of the class private data. The enum is public and is used here and there all over my application I decide to add another value to the enum and ... BAM! ... All instances throughout my project are reset to the first value of the enum. Kind of defeats the purpose of the enum, don't you think?! What do other people do? Define all enums fully during the design phase and never change them again? Label each instance of the enum with the desired value to provide some insurance against morphing? Don't use typedefs and update them all manually? 1 Quote Link to comment
mje Posted April 11, 2013 Report Share Posted April 11, 2013 This has happened to me often enough I'm paranoid about it. I think the use of it in a class is a red herring as I've seen my constants on the block diagram revert as well. I comment my constants now that way when it comes time to do a build, I can do a find all instances and "quickly" compare notes. I've also stopped using enums in a lot of situations. I tend to have more very simple classes now... Quote Link to comment
hooovahh Posted April 11, 2013 Report Share Posted April 11, 2013 I update type def'ed enums all the time. I think almost all of the time I am adding new values to the end, not updating, or removing them, maybe this is safer since the constants already in my application aren't having their values changed. Quote Link to comment
fabric Posted April 11, 2013 Author Report Share Posted April 11, 2013 Yeah. I guess empathy was what I was shooting for. I think almost all of the time I am adding new values to the end, not updating, or removing them, maybe this is safer since the constants already in my application aren't having their values changed. There might very well be something in this. Today I added a value in the middle and I think I often do that when the morphing occurs. Quote Link to comment
Yair Posted April 11, 2013 Report Share Posted April 11, 2013 I don't think I ever ran into this myself, but I have a vague recollection that this had to do with compiled code separation. I think there's a long thread in the NI forums on the subject. Quote Link to comment
todd Posted April 11, 2013 Report Share Posted April 11, 2013 That happened to me, the other day - added a value in the middle, and some constants changed. I have the vague recollection that a case structure changed, too. No time to repro and capture. Quote Link to comment
Darin Posted April 11, 2013 Report Share Posted April 11, 2013 The fundamental issue here is that Type definitions define type, not value. Of course NI has been beating people over the head for more than a decade now to type def enums and clusters so it would be poor form if they turned around and gave you that answer when you complain about this behavior. Now NI, as is their wont, stretch the definition of 'Type' definition a bit and try to accommodate this expected use case. This is as effective as the developers are in determining all of the corner cases. LV users delve into some very dark corners, so this is usually hard. Holes like this are likely bugs and probably get fixed in the usual (insert adjective here) timeframe. We are used to the fact that it is safer to explicitly bundle type def constants instead of relying on the values of BD constants. Maybe we should be doing the same thing here: Which brings up another thing that bites you every so often when updating td enums connected to Case structures. Sometimes a list 'a','c' gets silently changed to a range 'a'..'c' Quote Link to comment
fabric Posted April 11, 2013 Author Report Share Posted April 11, 2013 ... but I have a vague recollection that this had to do with compiled code separation Yes - my compiled code is separated... By the way, my current workaround for this is the old "pre-save, change, check, re-save" routine. Pre-saving the project before making any changes is starting to become second nature before editing any enum typedefs. Checking is a pain if you're paranoid, but usually I can tell if morphing has occurred by looking at any one instance. There seems to be an all-or-nothing pattern here... If there is suspicion, then I have found that saving the enum and then reverting the entire project usually does the trick, i.e. the morphing seems to be an edit-time effect and generally does not occur if the project is re-opened with a modified enum. (At least, this is what I have seen when adding values or deleting unused values...) Quote Link to comment
george seifert Posted April 12, 2013 Report Share Posted April 12, 2013 I've seen happen too when I change something in the middle of an enum, but it's fine if I make an addition at the end. George Quote Link to comment
Jordan Kuehn Posted April 12, 2013 Report Share Posted April 12, 2013 I've seen happen too when I change something in the middle of an enum, but it's fine if I make an addition at the end. George I've seen this behavior as well. Especially with case structures and simple 'state machines'. Quote Link to comment
Yair Posted April 14, 2013 Report Share Posted April 14, 2013 (edited) Which brings up another thing that bites you every so often when updating td enums connected to Case structures. Sometimes a list 'a','c' gets silently changed to a range 'a'..'c' This is an appropriate place to link to the relevant idea, which has way too few votes - http://forums.ni.com/t5/LabVIEW-Idea-Exchange/Case-structure-prevent-automatic-change-from-selector-value-list/idi-p/1687284 Edited April 14, 2013 by Yair Quote Link to comment
Mike Le Posted March 17, 2014 Report Share Posted March 17, 2014 I'm using LabVIEW 2013SP1 and am running into a similar issue. My compiled code is NOT separated from my VIs. I am trying to remove an Enum typedef (non-strict) from a class library. From the project window, I right-click on the typedef and select "Remove from library." Every time I've done this, it causes ALL the typdef's BD constants to revert to the default "0" value. This is enormously problematic, obviously. Clearing the compiled object cache as suggested here does NOT resolve the problem. I'm forced to revert to the earlier copy on source code control. But it's vital that I am able to remove the enumerated constant to untangle some undesirable code dependencies. Anyone have other troubleshooting suggestions? Quote Link to comment
mje Posted March 17, 2014 Report Share Posted March 17, 2014 What I've done in the past is open the typedef, right click on the icon to do a "find all instances", then document each constant's value with a comment (or really any means, comments are nice because you can do a #enum or something similar). Do what you need to to, then go back and double check your constants. Yes, it sucks, but I still don't trust LabVIEW as far as enums go. Quote Link to comment
Mellroth Posted March 17, 2014 Report Share Posted March 17, 2014 What I've done in the past is open the typedef, right click on the icon to do a "find all instances", then document each constant's value with a comment (or really any means, comments are nice because you can do a #enum or something similar). Do what you need to to, then go back and double check your constants. Yes, it sucks, but I still don't trust LabVIEW as far as enums go. Isn't it enough to open the typedef, and turn it into a ordinary control, apply changes, and then remove the typedef from the library? /J Quote Link to comment
mje Posted March 17, 2014 Report Share Posted March 17, 2014 Isn't it enough to open the typedef, and turn it into a ordinary control, apply changes, and then remove the typedef from the library? /J You would lose the linkage to the typedef. Also I'm not sure how LabVIEW would handle changing the control from a typedef to a control, it may very well mutate your constant values just as modifying the typedef would. Of course case structures completely throw a wrench in the plans I've mentioned above. Fun fun fun. 1 Quote Link to comment
Mellroth Posted March 17, 2014 Report Share Posted March 17, 2014 You would lose the linkage to the typedef. Also I'm not sure how LabVIEW would handle changing the control from a typedef to a control, it may very well mutate your constant values just as modifying the typedef would. Of course case structures completely throw a wrench in the plans I've mentioned above. Fun fun fun. I thought that MikeL wanted to remove the connection to the typedef while preserving the constant values. It is all about having fun ;-) Quote Link to comment
Mike Le Posted March 17, 2014 Report Share Posted March 17, 2014 Somehow I was able to get the result I wanted by the following procedure / magical ritual: Disconnected the typedef from the library. Saved ONLY the Enum .ctl file. Reopened the project, which now cannot find the .ctl file because it isn't part of the library as expected. Pointed LabVIEW to the exact same file location for the .ctl file. LabVIEW prompted me, warning me that there's a mismatch because the library was expecting the .ctl file to be part of the library, but the .ctl file wasn't expecting to be. Selected the option to resolve it in favor of disconnecting the .ctl from the library. Waited for the entire project to load, then checked the ~155 instances of the enum throughout the project. Found that none had been reset. Having to document every instance of the enum is sort of ridiculous. At that point, I think I'd rather use OpenG "select enum value by string name" primitive and implement Darin's "dare to dream" scenario. But that seems like it'd cause a ton of needless overhead... 1 Quote Link to comment
PaulL Posted March 17, 2014 Report Share Posted March 17, 2014 I guess I'm a little puzzled why some people see this and some people don't. What is different? I use strict typedefs quite frequently. Quite often I place instances in class private data and constants fromt the typedefs in class methods. Note that the .ctl files for the typedefs are in separate .lvlib files. When I need to change a typedef I open it within the project, make modifications, apply the changes, and save. I avoid things like renaming an item and inserting another item in the same step, which could obviously cause problems. As long as I am careful in this respect, I don't (or haven't yet) encountered major issues. Maybe I've just been lucky. I'm puzzled what the difference is. 1 Quote Link to comment
ShaunR Posted March 17, 2014 Report Share Posted March 17, 2014 (edited) I guess I'm a little puzzled why some people see this and some people don't. What is different?I use strict typedefs quite frequently. Quite often I place instances in class private data and constants fromt the typedefs in class methods. Note that the .ctl files for the typedefs are in separate .lvlib files. When I need to change a typedef I open it within the project, make modifications, apply the changes, and save. I avoid things like renaming an item and inserting another item in the same step, which could obviously cause problems. As long as I am careful in this respect, I don't (or haven't yet) encountered major issues. Maybe I've just been lucky. I'm puzzled what the difference is. I too have never experienced it. But I remember Daklu writing an example (on lavag) to prove me wrong and that it does really happen.lol Maybe the Lavag historian can find it-I cannot currently I vaguely remember that the reason that I never see it, is because my workflow is to have all the VIs in memory. IIRC, when you change a typedef, the VIs not in memory are not updated,(of course) and so the change is not propagated., When they are next loaded labview isn't able to resolve the discrepancy and resets them to the zero value. LabVIEW is able to resolve the difference if the new value is at the end, but not in the middle. So I think I suggested having the old-style VI Tree just so that you could force LabVIEW to load all the VIs. Since my workflow is to produce examples that act as regression test harnesses, the examples keep all the VI hierarchy in memory so I never see it. Edited March 17, 2014 by ShaunR Quote Link to comment
Havard Posted August 4, 2015 Report Share Posted August 4, 2015 Hi there, I ran into this issue now. We should have used some other method for enumerating IO pins. Here are some results of my tests: OK Adding one or multiple items Edit one or multiple items Data corruption Removing used items (constants of the removed value(s) change) Edit and add combined (some or all constants in project change) Edit and remove combined (some or all constants in project change) Quote Link to comment
Yair Posted August 5, 2015 Report Share Posted August 5, 2015 I wonder if this can work: Open the typedef. Save the enum control somewhere. Replace the enum with a numeric. Apply the changes. Do your disconnecting. Replace the numeric with the enum you saved. Apply the changes. A quick test indicates that replacing a an enum with a constant and a constant with an enum preserves the value, but I don't know if this applies when you do it with a typedef and I don't know if it will help with this specific issue even if it does work on typedefs. My guess would be no, because whatever's resetting the value will probably still happen at some point in this process, but that's just a guess. Quote Link to comment
hooovahh Posted August 5, 2015 Report Share Posted August 5, 2015 BTW in 2014 a new feature was added for finding and reviewing enum changes like this. Quote Link to comment
fredb Posted November 30, 2015 Report Share Posted November 30, 2015 Thanks, Mike Le for your workaround - that did not quite work for me, but it did lead me to figure out how to resolve my instance of this problem. We have an enum type def tucked away in a class. Actually - we have many. Like hundreds. We typically drop the type def on the BD and pass it in to a connector pane, or a shift register into a case statement, or.... Every now and then, some of the constants would revert to the 0'th element of the enumeration. What Mike suggested in this thread works - but I ran into two problems: 1. When I added the type def back into the class, the problem came back. 2. It does not help me identify which of the hundreds of places where I use enums are affected. So, the solution (hopefully this will help you if you run into this) is gloriously simple. Clear the object cache! Go to Tools>Advanced>Clear Compiled Object Cache Make's sense to me now. This should be the second step in building an executable (the first being grabbing the sources from your repository). Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.