I get a little bored writing getting and setters for a class. Especially if there's a fair few of them and they all look nearly identical.
It makes me wonder that, if you are publically allowing a user to both read from AND write to a variable and aren't performing any checks/modifications, shouldn't it just be made public?
If not, then would an approach like this be viable?
enum Action{ GET, SET };
template<typename Type>
Type process(Action action, Type& num, Type newVal = 0) { // gfvalvo has good eyes
return action > GET ? num = newVal : num;
}
example usage:
int a;
float b;
bool c;
process(SET, a, 42);
int x = process(GET, a);
process(SET, b, 42.2);
float y = process(GET, b);
process(SET, c, true);
bool z = process(GET, c);
Yeah that's a whoops right there. I typed it up for int then thought I'd add the others. I will make an edit.
(to continue)
Or, simply:
template<typename Type>
Type get(Type& t) { return t; }
template<typename Type>
void set(Type& t, Type y) { t = y; }
It just seems pointless when they might as well be public anyway, but I've tried to always write them as I thought it was 'correct practice'.
My only justification is thinking that making it public now, could cause issues later when you want to change things and the variable is now scattered about in code.
Having get/set could 'future' proof for changes by having a nice access point where modifications can be made easily without breaking existing code.
That's a bad sign. Why is that the case? If the variables are associated, you might consider using a struct and having one get/set method for the struct.
In many cases, yes, making the member public is a perfectly fine choice.
However, consider the following:
If you want to maintain some kind of class invariant or want to perform error or bounds checking, you need to use a setter.
If you make a member public, you cannot replace it with a setter later without breaking your API.
I don't think this is better than the standard getter/setter approach. Granted, that requires some boilerplate, but it's much less of a surprise to users or casual readers of your code, which I would argue is more important.
Then you probably need a better IDE
For example, VSCode allows you to define your own snippets, so adding a default getter/setter pair can be done in a handful of keypresses.
Consider the 'print' method. Sure, the definition is long winded for all the variable types that must be handled, but in the end the user view is extremely simple. That's what counts.
You could use something like this: In VSCode, use Ctrl+Shift+P and search for Configure User Snippets. Then select cpp.json (C++) and add the following:
You could add more fancy features, such as rvalue or even forwarding references for the setter, or you could disallow getting a mutable reference, but you get the idea.
warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
if (someObj.someMemberVar = 42) {
~~~~~~~~~~~~~~~~~~~~~~^~~~
note: place parentheses around the assignment to silence this warning
if (someObj.someMemberVar = 42) {
^
( )
note: use '==' to turn this assignment into an equality comparison
if (someObj.someMemberVar = 42) {
^
==
Then the only ones to blame are the developers who chose to disable warnings by default, and the users who choose to ignore them. Either way, the burden should not be on library developers, and it should not be a reason to write getters for members that wouldn't otherwise require them.
I do think that this is an important issue, but this is not the solution, the community needs a change in attitude towards warnings, starting here on the forum.
I'm certainly on the -Wall -Werror -Wextra team, but I just don't think you are being realistic. The focus of Arduino is on providing a gentle learning curve to embedded systems for normal people. That includes avoiding footguns in interfaces where possible.
I agree, but things like that are just a drop in an ocean of other possible footguns, and IMHO not worth the additional cognitive load while developing an API.
I'd argue that warnings are important for programmers at any level, but especially for beginners and normal people, who might not be familiar with the obvious pitfalls of the language.
Beginners often make obvious errors that the compiler can warn about quite easily, and I believe that it's much more productive and motivating to have the compiler print a message than to have to debug a microcontroller that doesn't do anything.
Unfortunately, it seems that some Arduino developers do not share this opinion, and even if they did, at this point it would be very hard to turn up the default warnings in the IDE without flooding users with warnings for old code or poorly written libraries.
On the other hand, there is definitely room for improvement, e.g. making new users aware that warnings exist in the first place, providing more granular warning options, separating library warnings from sketch warnings, giving an option to create new sketches with a set of “recommended” warnings, switching to a more modern compiler with more readable warnings, colored compiler output to make it easier to read, real-time yellow warning squiggles in the IDE, a dedicated “warnings and errors” tab instead of the plain text compiler output, etc.
Some of these last things are supported by Eclipse Theia, on which the Arduino IDE 2.0 is based, but it seems that they disabled (or at least hid away) those features in the most recent betas