2

I'm thinking about how to debug better without using Getters/Setters. If it helps, I program using xcode.

Many answers in Stack Exchange have argued against Getters/Setters for lack of encapsulation (read: When are Getters and Setters Justified), but my reasoning for now is that I use them for easier debugging; setting a break-point at the getter/setter is way easier than hunting down every point where the variable is accessed.

Smart naming partially solves this problem since I can quickly search for the variable name, but doesn't solve my issue of having to find every access/modification of the variable; I still have to set break-points everywhere.

Is there an easy way to avoid getters and setters whilst discovering when my variables are modified/accessed in an easy way?

PS. I hope I'm not making some stupid rookie mistake, or being ignorant of some cheap and simple xcode hack here.

Edit: Maybe I should elaborate a little more. Often, the variables I want to check on are directly accessed/modified. I just want to know when the variable is accessed/modified easily.

5
  • There should be only a few places (meaning five or less) where any given class member is modified. Perhaps you should post your class definition to give us an idea of your problem. Mar 29, 2016 at 10:10
  • That's the thing, I can't guarantee that there will only be a few places. Many of the classes I work with (working in a team, and I'm the newbie) from what I can see exhibit more struct-like behaviour, in that other classes can get/set them freely. So encapsulation and interfaces as good practices are pretty much out the window for me here. Implementing getters/setters is one way I tried to alleviate this problem. As long as my team-mates see my intent and use the getters/setters, things should work.
    – Mark Ang
    Mar 29, 2016 at 10:19
  • hunting down every point where the variable is accessed doesn't the debugger allow you to add breakpoints which break execution whenever a memory location (the memory for the variable) is accessed?
    – stijn
    Mar 29, 2016 at 10:26
  • 1
    When you say memory location, you mean for that one instance of the variable right? If so, would probably work well for singletons, otherwise I'll have to do it for every instance. And if the class instances are dynamically created/destroyed... let's not go there.
    – Mark Ang
    Mar 29, 2016 at 10:43
  • Sounds like your team is well on the way to creating a Big Ball of Mud. The advice about get/set methods does not apply to structs. In that case get/set is bad but it's far better than having public data members. You might want to start looking for another position. This project is not going to be fun. Mar 29, 2016 at 23:19

5 Answers 5

1

PS. I hope I'm not making some stupid rookie mistake, or being ignorant of some cheap and simple xcode hack here.

The xcode debugger supports breakpoints when a variable is modified.

Is there an easy way to avoid getters and setters whilst discovering when my variables are modified/accessed in an easy way?

Generally, don't write them.

You will have cases when you need a getter or a setter, but that is only if your object has the explicit functionality of getting/setting a value (for examples, see std::unique_ptr::get, or boost::optional::get).

In most other cases, you should be able to avoid exposing a class' privates.

0

Avoiding getters/setters is not about direct access of member variables, but deciding what interface to expose for your class.

eg. For a Person class, instead of having an 'age' member and a getter that simply returns this variable, you should be thinking about a better way to represent the operations on the Person. An example would be to store the date of birth and then provide a getter for age that calculates it.

So you should still have a method for accessing your class, just not a mindless method that corresponds to each member variable.

5
  • 1
    Sorry, I'm not sure how this answers my question. I'm looking for a way to better discover when my class's variables are accessed/modified.
    – Mark Ang
    Mar 29, 2016 at 7:59
  • you use methods and hide all variable access behind them. It is still bad practice to have a method that exists just to expose a single variable however.
    – gbjbaanb
    Mar 29, 2016 at 8:01
  • Alright. My question is: Is there a better way to check when a variable is modified/accessed than to break-point every line where said variable is modified/accessed?
    – Mark Ang
    Mar 29, 2016 at 8:04
  • Check your compiler, some will allow breakpoints on memory locations. MSVC will do this but you will have to reset the breakpoint to reflect the actual memory location every run, and its much slower.
    – gbjbaanb
    Mar 29, 2016 at 8:05
  • Check your debugger's documentation. It should be able to set breakpoints on access to variables (something like "stop execution when X is about to be read/written").
    – Mael
    Mar 29, 2016 at 9:06
0

If you need getters and setters for debugging purposes, you can always wrap your variables, and remove the wrapper afterwards (or simply allow it to be elided by the optimizer). The wrapper needs an implicit conversion constructor, cast operators etc, something like this (note - completely untested code):

template <typename T>
struct Wrapper {
  Wrapper() {}
  Wrapper(T v) : val_(v) {}
  // default all copy/move constructors and assignment operators
  operator T () const { return val_; }
  operator T&() { return val_; }
  // also assignment from T, and any other required operators
private:
  T val_;
};

This should have pretty much no effect (at least for primitive types), but gives you somewhere to set breakpoints.

If you're interested in specific instances you can just use a watchpoint with no code change (something like this, presumably, although I don't use xcode).

0

It is implementation specific, depending both on the compiler (& compilation options) and on the debugger (& debugger commands).

With a recent GCC compiler (GCC 5.3 or better in march 2016) using a recent GDB debugger (GDB 7.11 or better in march 2016, with both Python & Guile support enabled at build time thru appropriate options to configure) on Linux, you might script GDB in Python or Guile, hence customizing it to suite your needs (so you could make it pretty-print some of your classes or containers like you want). Sadly, I am not good at this today (because I am a bit lame, and mostly because the documentation is incomplete). You'll probably also be interested by GDB watchpoints.

BTW, getters and setters are often inlined, so might not matter (performance wise) in production code.

0

XCode/lldb call this a watchpoint.

You can set a watchpoint on the variable in question, so execution will stop any time a variable is read or written.

You can set a watchpoint in XCode by going to the Variables view, right clicking the variable you care about in the list, and on the pop-up menu selecting "Watch foo" (where foo is replaced by the name of the variable in question). By default this only triggers on writes to that variable.

If you want more control than that, you can open the lldb console window, and use lldb commands to set your watch point. This will let you set a break on read, or (for example) only break when a specific value is written.

If you type "Help watchpoint" into the lldb console, it should give you more details. You might also want to read the "SETTING WATCHPOINTS" section in the lldb tutorial.

I'd add that at least in my opinion, this shouldn't be called a "hack".

If you use your shirt as a water filter that is (or at least might qualify as) a hack.
If you wear your shirt as it's designed to be worn, that's just wearing a shirt.

This is much the same: it's not even attempting to invent some clever new way to use XCode or lldb to accomplish some strange mission for which they weren't really designed. Rather, it's just using a feature of the debugger exactly as intended to do exactly what it was designed to do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.