New to creating libraries, I would like some comments.

Hi;

I have been working to learn how to create libraries for Arduino. I decided to create a simple Math library to assist me in learning. I read the tutorials but they didn’t show how to send values and get return values.

I seem to have created a fully functional library but I am sure there are flaws that I am not aware of. I ask for creative comments as to how to improve my libraries. I have attached my library.
(Please be kind, I am new)
Thanks in advance

Mike

Math.zip (1.51 KB)

I read the tutorials but they didn’t show how to send values and get return values.

Sure they do. Functions take arguments and return values. It doesn't matter whether the function is in a class (and, therefore called a method), or not.

   return(_res);

(Why)(is)(the)(value)(in)(parentheses)? Whyistherenospacebetweenthecommandandtheargument?

It is best to avoid underscores in variable names. There is no reason for any of your variable names to have underscores.

There is no reason for your constructor to take arguments. You never use the fields that you assign the values to.

You are mixing naming conventions in your code for arguments and member variable, which isn't a good practice. Also class != library. Library is (usually) a collection of several classes and/or free functions. Also your Math class doesn't make much sense, but I take this is just an exercise how to write reusable code rather than writing something useful.

Cheers, Jarkko

Library is (usually) a collection of several classes

Not true. Many quite useful libraries contain exactly one class.

I'm pointing out obvious mistake that people think class == library. Also note the word "usually"

PaulS:

   return(_res);

(Why)(is)(the)(value)(in)(parentheses)? Whyistherenospacebetweenthecommandandtheargument?

I thought it needed the parentheses, A space would make it more readable.

It is best to avoid underscores in variable names. There is no reason for any of your variable names to have underscores.

I understood that was common practice, as per the tutorial here http://arduino.cc/en/Hacking/LibraryTutorial. where they state "Adding an underscore to the start of the name is a common convention to make it clear which variables are private,"

There is no reason for your constructor to take arguments. You never use the fields that you assign the values to.

Ok, I was testing and it seemed to work. I will try without.

These are such great comments, I don't think I will be able to keep up. But I knew I would get some fantastic help here.

Thanks

I understood that was common practice, as per the tutorial here http://arduino.cc/en/Hacking/LibraryTutorial. where they state "Adding an underscore to the start of the name is a common convention to make it clear which variables are private,"

That is not a common convention. Using something like m_ in front of member names is common. Leading underscores have special significance to some compilers, and should not be used the way the library page suggests. While the code will work on the Arduino, it isn't good practice.

And, the convention applies ONLY to class members, NOT to local variables or method arguments.

For learning purpose take a look at this.

That is not a common convention. Using something like m_ in front of member names is common. Leading underscores have special significance to some compilers, and should not be used the way the library page suggests. While the code will work on the Arduino, it isn't good practice.

And, the convention applies ONLY to class members, NOT to local variables or method arguments.

This is actually common convention and perfectly valid as well, though I personally prefer m_ prefix for member variables. Underscore prefixed names are not reserved as you claim either. More specifically underscore prefix followed_by capital letter are reserved for implementation as are names with double underscore in them.

Cheers, Jarkko

JarkkoL:
You are mixing naming conventions in your code for arguments and member variable, which isn't a good practice.

I think I understand what you are saying; could you point me to a resource that would assist me in learning conventions and scope. Is scope correct?

Also your Math class doesn't make much sense, but I take this is just an exercise how to write reusable code rather than writing something useful.

You are 100% correct, I chose to do something very simple in order to learn. The KISS method, I am the second 'S'.

Thanks
Mike

While still stumbling in the dark a little, I think I may see some light in the distance. I have taken the suggestions provided and I think I have made improvements.
Please have a look and provide comments. I have attached my library.

Thanks
Mike

Math.zip (1.57 KB)

I am the second 'S'.

I don't think so. You posted code that worked, and asked for comments. You are attempting to understand and incorporate the comments (which are contradictory, to say the least).

'S' would be to post non-working code, ask for help, and then reject all attempts to help.

You could use m_someName as a member variable, and someName as a local variable, and perhaps a_someName as an argument variable's name. However, the context where a variable is used will usually define whether it is a member variable, a local variable, or an argument. This is especially true if the names are meaningful, which is far more important than following a convention, and if the functions are small (which they should be).

The best advice is to use what feels natural to you and to be consistent. And, of course, to use names that make sense.

int Math::add(int dog, int banana)
{
   int tiger = dog + banana;
   return tiger;
}

is an example of names that make no sense.

Like Paul said it's important to be consistent and pick good expressive names, but I don't agree you should just pick a convention that feels natural. There are some quite widely used conventions and it's good to adopt those so that other people can more easily understand your code. Some conventions I use that are also quite widely used:

  1. m_ prefix for private/protected member variables, e.g. int m_foobar; and without for public member variables, e.g. int foobar;
  2. underscore postfix for arguments, e.g. void foo(int bar_); most code I see use the same convention as local variables though but I like to differentiate those.
  3. for local variables use the name without any pre/postfix, e.g. int foobar;
  4. for static variables use s_ prefix, e.g. static int s_foobar; some people use ms_ for class static vars, but I haven't seen much use for this and use the same prefix regardless of scope (function, class, file).
  5. for global variables use g_ prefix, e.g. int g_foobar; in a (global) namespace (note that you should try to minimize use of these to avoid spaghetti code)
  6. for macro names use all caps and separate words with underscore (e.g. #define MY_MACRO 1)
  7. pick either CamelCase or underscore notation e.g. int myOwnVariable; or int my_own_variable; I'm using underscore like the C++ standard lib, but many people opt to use CamelCase. Common variant of CamelCase is to start with low-case for variables and function names, e.g. int myVariable; while starting with upper-case for class names, e.g. class MyClass; Some people also prefix class names with C for concrete classes (i.e. something you can instantiate), e.g. class CMyClass; and I for abstract interface classes, e.g. class IMyInterface;

I don't use Hungarian notation in variable names and neither should you as I find it an obsolete relic from C. There's quite a bit more what comes to consistent coding convention though and it can end up in some heated discussions with some "religious" opinions on both sides of the fence :wink: Like should you write "int x;" or "int x;", or use Egyptian brackets, or how to add spaces to argument lists, or use tabs vs spaces for indention, etc. etc. Anyway, I think the above is a good start.

Cheers, Jarkko

For coding style I recommend Ellemtel. Used it on every C++ project I've done in the last 20 years...
http://www.doc.ic.ac.uk/lab/cplus/c++.rules/

SomeAssembly:
I have been working to learn how to create libraries for Arduino. I decided to create a simple Math library to assist me in learning. I read the tutorials but they didn’t show how to send values and get return values.

It seems that you are mixing new data types (class instances) with operations. This is how I would do that

in .h:
class Math
{
public:
static int add(int a, int b);
static int subtract(int a, int b);
...
};

in .cpp
int Math::add(int a, int b) {
return a + b;
}

when using:
int result = Math::add(1, 2);


Alternatives

  1. Have everything in .h

static int add(int a, int b) {
return a + b;
}

  1. Have it with 'inline' for faster execution

static inline int add(int a, int b) {
return a + b;
}

  1. Don't bother with classes, just have functions

extern int math_add(int a, int b); // in .h

int match_add(int a, int b) { // in .cpp
return a + b;
}

  1. Use name spaces

namespace math {
extern int add(int a, int b); // in .h
}

usage:
int result = math::add(1, 2);


Arduino libraries use the instance member reference notation like Serial.println with some instance that is hidden from you but C++ provides other approaches as well.

One other issue with libraries is to add enough meta data so when it is for real and you get feedback from the field it is easier to help. This is my (more or less) standard meta-header
//
// FILE:
// AUTHOR:
// VERSION: 0.1.03
// PURPOSE:
// DATE:
// URL:
//
// Released to the public domain
//

Another point the name of the lib should be unique, math is already in use