Shop OBEX P1 Docs P2 Docs Learn Events
Written But Never Read Variables — Parallax Forums

Written But Never Read Variables

KyeKye Posts: 2,200
edited 2014-07-08 13:27 in Propeller 1
Does GCC optimize out written but never read variables in an object?
class thingy
{

public:

 void setVar(int newVar) { var = newVar; doCoolStuff(); }
 int getVar() const { return var; }

 void doCoolStuff() { ... }

private:

  int var;
}

So, for example, calling setVar() calls the doCoolStuff() function and sets the value of var. If getVar() is never called then the var private variable is not needed. So, is GCC smart enough to remove this unused variable?

I wrote an object that has a large payload of cache variables like this that are written but never read. Since I need to save RAM I'm wondering if removing them will help.

Comments

  • jazzedjazzed Posts: 11,803
    edited 2014-07-08 07:46
    Just add inline to the functions.

    inline int getVar() const { return var; }
  • ersmithersmith Posts: 6,054
    edited 2014-07-08 08:11
    Kye wrote: »
    Does GCC optimize out written but never read variables in an object?
    It depends on the circumstances. If GCC thinks some external code (in another file) might read the variables, then it won't optimize them away. If it knows that it can "see" all uses of the variables (for example, if the object is declared static so outside code cannot access it) then it will remove unnecessary assignments.

    In general it might make sense to separate the "setVar" so that it only sets a variable, and rely on the user to call "doCoolStuff()" manually.
  • KyeKye Posts: 2,200
    edited 2014-07-08 09:52
    Let me clear up what I am doing:

    https://github.com/omniacreator/omniacreator-plugin/blob/master/interfacelibrary/iloscilloscopegraph.h
    [COLOR=#445588][B]bool[/B][/COLOR] setValueErrors([COLOR=#445588][B]bool[/B][/COLOR] valueErrors,
    
                            [COLOR=#445588][B]bool[/B][/COLOR] waitForResponse [B]=[/B] [COLOR=#0086B3]false[/COLOR])
        {
            [COLOR=#445588][B]bool[/B][/COLOR] result;
    
    
            [B]if[/B]((result [B]=[/B]
            sendPacket(OSCILLOSCOPE_SET_GRAPH_VALUE_ERRORS,
            int32(valueErrors), waitForResponse)))
            {
                m_valueErrors [B]=[/B] valueErrors;
            }
    
    
            [B]return[/B] result;
        }
    
    
        [COLOR=#445588][B]bool[/B][/COLOR] getValueErrors([COLOR=#445588][B]bool[/B][/COLOR] bypassCache [B]=[/B] [COLOR=#0086B3]false[/COLOR],
                            [COLOR=#445588][B]bool[/B][/COLOR] [B]*[/B]ok [B]=[/B] [COLOR=#009999]0[/COLOR])
        {
            [COLOR=#445588][B]bool[/B][/COLOR] result [B]=[/B] m_enabled;
    
    
            [B]if[/B](result [B]&&[/B] bypassCache)
            {
                int32 response;
    
    
                [B]if[/B]((result [B]=[/B]
                receivePacket(OSCILLOSCOPE_GET_GRAPH_VALUE_ERRORS,
                [B]&[/B]response)))
                {
                   m_valueErrors [B]=[/B] [COLOR=#445588][B]bool[/B][/COLOR](response);
                }
            }
    
    
            [B]if[/B](ok)
            {
                [B]*[/B]ok [B]=[/B] result;
            }
    
    
            [B]return[/B] result [B]?[/B] m_valueErrors : [COLOR=#445588][B]bool[/B][/COLOR]();
    
        }
    
    private: [COLOR=#445588][FONT=Consolas][B]bool [/B][/FONT][/COLOR][COLOR=#333333][FONT=Consolas]m_valueErrors[/FONT][/COLOR][COLOR=#333333][FONT=Consolas];[/FONT][/COLOR]
    

    So, all the code is in a class in a header only library. This means that the C file that includes my header only library can see everything.

    I have these get and set functions which generate serial traffic and can take a long time to execute. So, to speed up the get function which has to ask an external computer for a data value I just cache the value when you set it.

    As long as you don't call the get function the cached value is never needed.

    As you can see in that file I linked to... the number of private variables has grown quite large... and may continue to grow if I add more features to these classes.
  • Heater.Heater. Posts: 21,230
    edited 2014-07-08 10:47
    The question is then, does GGC analyse your entire program and figure out what is used and what is not?

    If the methods that read an objects state are never called then the compiler could, in theory, remove all the calls to methods that set that state.
    As far as I know optimization is only done on a per file basis so the information is not available to the compiler to make such pruning.
    Unless someone knows a magic option to get the compiler to optimize globally.

    Marking methods as "inline" might do it, but as far as I know "inline" is only a suggestion.

    Bottom line is, compile the thing, dump the resulting assembler and see what you have got.
  • KyeKye Posts: 2,200
    edited 2014-07-08 12:01
    > Bottom line is, compile the thing, dump the resulting assembler and see what you have got.

    Any easy way to go about doing that using SimpleIDE? The library is about 17K LOC.
  • Heater.Heater. Posts: 21,230
    edited 2014-07-08 12:35
    Not from SimpleIDE. SimpleIDE is supposed to be simple. right?

    Off the top of my head I'm not sure but if you can set the -g option in SimpleIDE to compile and include debugging symbols in the executable that is a good start.

    Then you need to go to the command line and use the propgcc objdump command with the -A or -a options. Then you can search te output for the methods you think should or should not be there.

    It's a long time since I have done this kind of thing, sorry to not be more specific.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-07-08 13:04
    As long as the function that reads the variable is accessible externally there is a chance that the variable will be read. So the compiler must keep the variable. If fact, I think the compiler will keep the variable even if you only write to it. At least I tried that experiment with C code, and the compiler did not optimize out a write-only variable. However, the compiler will remove the variable if there is no code that accesses it. It will also remove the variable and the set and get functions if they are static, and they are not called within the file. If you have warnings enable you will get a warning that the variable is not used.
  • jazzedjazzed Posts: 11,803
    edited 2014-07-08 13:05
    Kye wrote: »
    > Bottom line is, compile the thing, dump the resulting assembler and see what you have got.

    Any easy way to go about doing that using SimpleIDE? The library is about 17K LOC.

    Sure :)

    Open the Project manager and right click on some filename to get the Popup window. You can also Enable Pruning in the Compiler tab to do compile time "garbage collection" (not memory management).
  • Heater.Heater. Posts: 21,230
    edited 2014-07-08 13:27
    Jazzed, what is "Enable Pruning" as a real GCC command line option? Sounds like good stuff.
Sign In or Register to comment.