Library question : error : Class does not name a type

Hello,

I wrote a function and thought I would attempt to put it inside a library (MyLib) to use it inside another sketch. I did the following:

  • Created a MyLib.h file
  • Created a MyLib.cpp file
  • Created a keywords.txt file

Then, I tried to use that function through the library inside a new sketch.

At the top, I put:

#include <MyLib.h>
MyLib mylib;

When attempting to compile, I get the following error:

Arduino\libraries\MyLib/MyLib.h:6:1: error: 'Class' does not name a type

Class MyLib

I have tried many things but I just can't figure it out.

This is the code for the original function before being put inside the library:

char* IntToFmt(int num, int digit, char delim) {
  int nDigits = floor(log10(abs(num))) + 1;                           
  char *numchr;                                                       
  numchr = (char *) malloc(sizeof(char) * (nDigits+1));               
  char *fmtchr;                                                       
  int numlen;                                                         
  int delimnum;                                                       
  int fmtnumlen;                                                      
  int adj = 0;                                                        
  double ratio;                                                       
  itoa(num, numchr, 10);                                              
  numlen = strlen(numchr);                                            
  if (num < 0 && (numlen-1) % digit == 0) {
    adj = 1;                                                          
  }
  ratio = ceil(1.000 * (numlen-adj) / digit);                         
  delimnum = ratio - 1;                                               
  fmtnumlen = numlen + delimnum;                                      
  fmtchr = (char *) malloc(sizeof(char) * (fmtnumlen+1));             
  int a = 0;                                                          
  int b = fmtnumlen - 1;                                              
  for (int c = 0; c < (fmtnumlen); c++) {
    //Serial.println((c + 1) % (digit + 1));
    if (c!=0 && (b + 1 ) % (digit + 1) == 0) {                        
      fmtchr[c] = delim;
    }
    else {
      fmtchr[c] = numchr[a];
      a++;
    }
    b--;
  }
  fmtchr[fmtnumlen] = '\0';                                           
  return fmtchr;
  free(fmtchr);                                                       
  free(numchr);                                                       
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(74880);
  int blcksiz = 3;
  char delimchar = ',';

  int a = 123456;
  int b = 1234567;
  int c = 12345678;
  int d = 123456789;
   
  int w = -123456;
  int x = -1234567;
  int y = -12345678;
  int z = -123456789;

  Serial.println("");
  Serial.println("The formatted result of a is : " + String(IntToFmt(a, blcksiz, delimchar)));
  Serial.println("The formatted result of a is : " + String(IntToFmt(b, blcksiz, delimchar)));
  Serial.println("The formatted result of a is : " + String(IntToFmt(c, blcksiz, delimchar)));
  Serial.println("The formatted result of a is : " + String(IntToFmt(d, blcksiz, delimchar)));
  Serial.println("");
  Serial.println("The formatted result of a is : " + String(IntToFmt(w, blcksiz, delimchar)));
  Serial.println("The formatted result of a is : " + String(IntToFmt(x, blcksiz, delimchar)));
  Serial.println("The formatted result of a is : " + String(IntToFmt(y, blcksiz, delimchar)));
  Serial.println("The formatted result of a is : " + String(IntToFmt(z, blcksiz, delimchar)));
}

void loop() {
  // put your main code here, to run repeatedly:
}

This is the content of the .h file:

#ifndef MyLib_h
#define MyLib_h

#include "Arduino.h"

Class MyLib
{
	public:
		MyLib();
		char* IntToFmt(int num, int digit, char delim);
	private:
		int _num;
		int _digit;
		char _delim;
		int _nDigits;
		char *_numchr;
		char *_fmtchr;
		int _numlen;
		int _delimnum;
		int _fmtnumlen;
		int _adj;
		double _ratio;
		int _a;
		int _b;
		int _c;
};

#endif

This is the content of the .cpp file:

#include <Arduino.h>
#include <MyLib.h>

MyLib::MyLib()
{
}

char* MyLib::IntToFmt(int num, int digit, char delim) {
  _num = num;
  _digit = digit;
  _delim = delim;
  _nDigits = floor(log10(abs(_num))) + 1;
  _numchr = (char *) malloc(sizeof(char) * (_nDigits + 1));
  _adj = 0;
  itoa(_num, _numchr, 10);
  _numlen = strlen(_numchr);
  if (_num < 0 && (_numlen - 1) % _digit == 0) {
    _adj = 1;
  }
  _ratio = ceil(1.000 * (_numlen - _adj) / _digit);
  _delimnum = _ratio - 1;
  _fmtnumlen = _numlen + _delimnum;
  _fmtchr = (char *) malloc(sizeof(char) * (_fmtnumlen + 1));
  _a = 0;
  _b = _fmtnumlen - 1;
  for (int _c = 0; _c < (_fmtnumlen); _c++) {
    if (_c != 0 && (_b + 1 ) % (_digit + 1) == 0) {
      _fmtchr[_c] = _delim;
    }
    else {
      _fmtchr[_c] = _numchr[_a];
      _a++;
    }
    _b--;
  }
  _fmtchr[_fmtnumlen] = '\0';
  return _fmtchr;
  free(_fmtchr);
  free(_numchr);
}

This is the content of the .txt file:

MyLib	KEYWORD1
IntToFmt	KEYWORD2

The 3 files are in the Arduino/libraries/MyLib folder.

If anybody could help to find where I messed-up it would be great.

Thanks.

Arduino\libraries\MyLib/MyLib.h:6:1: error: 'Class' does not name a type

Should be a lowercase c on class

class (with small c) is a keyword and not Class (with capital C). We use class keyword to create a data type/tag which in turn is used to declare/create object.

class MyLib //MyLib is a data type/tag
{
   //variables and functions declaration
};

MyLib mylib; //mylib is an object[/ode]

Fantastic, you guys hit the nail on the head. A detail with large implications as always in programming.

Changed class to lowercase in the header file and it compiles perfectly now.

Thank you so much!

I tried to add a second function inside the library and I get the following error now:

error: '_str' was not declared in this scope  _str = str;

This is odd as the variables are declared the same way as for the previous function. It does this for all the private variables used inside the new function. They are declared inside the private section of the header file and then used in the cpp file.

This is was the code for the header file now looks like:

#ifndef MyLib_h
#define MyLib_h

#include "Arduino.h"

class MyLib
{
	public:
		MyLib();
		char* IntToFmt(int num, int digit, char delim);
		char* StrToChar(String str);
	private:
		int _num;
		int _digit;
		char _delim;
		int _nDigits;
		char *_numchr;
		char *_fmtchr;
		int _numlen;
		int _delimnum;
		int _fmtnumlen;
		int _adj;
		double _ratio;
		int _a;
		int _b;
		int _c;
		String _str;
		int _str_int;
		char *_buf;
};

#endif

And this is what the cpp file now looks like:

#include <Arduino.h>
#include <MyLib.h>

MyLib::MyLib()
{
}

char* MyLib::IntToFmt(int num, int digit, char delim) {
  _num = num;
  _digit = digit;
  _delim = delim;
  _nDigits = floor(log10(abs(_num))) + 1;
  _numchr = (char *) malloc(sizeof(char) * (_nDigits + 1));
  _adj = 0;
  itoa(_num, _numchr, 10);
  _numlen = strlen(_numchr);
  if (_num < 0 && (_numlen - 1) % _digit == 0) {
    _adj = 1;
  }
  _ratio = ceil(1.000 * (_numlen - _adj) / _digit);
  _delimnum = _ratio - 1;
  _fmtnumlen = _numlen + _delimnum;
  _fmtchr = (char *) malloc(sizeof(char) * (_fmtnumlen + 1));
  _a = 0;
  _b = _fmtnumlen - 1;
  for (int _c = 0; _c < (_fmtnumlen); _c++) {
    if (_c != 0 && (_b + 1 ) % (_digit + 1) == 0) {
      _fmtchr[_c] = _delim;
    }
    else {
      _fmtchr[_c] = _numchr[_a];
      _a++;
    }
    _b--;
  }
  _fmtchr[_fmtnumlen] = '\0';
  return _fmtchr;
  free(_fmtchr);
  free(_numchr);
}

char *StrToChar(String str) {
	_str = str;
  _str_int = _str.length() + 1;
  _buf = (char *) malloc(sizeof(char) * (_str_int + 1));
  str.toCharArray(_buf, _str_int);
  return _buf;
  free(_buf);
}

Does anybody have a clue as to why the private variables of the new function added to the library are not being picked-up?

Also, as a side question, can 2 functions use a private variable with the same name? This is not the case here but I was just wondering.

Thanks.

Scope Resolution

char * MyLib::StrToChar(String str) {

:o I am really struggling with these library files, keep missing those 'details' and looking in the wrong spots. You got it, that was my mistake indeed...

Thank you!

str.toCharArray(_buf, _str_int);
~~ return _buf;~~
~~ free(_buf);~~
}
You are returning a dangling pointer
Reply below.

And the free() function will never be executed

Thanks to both of you for the floating pointer / free() comments.

Currently, doing it wrong looks like this:

char *myfunc(String str) {
  int str_int = str.length() + 1;
  char *buf;
  buf = (char *) malloc(sizeof(char) * (str_int + 1));
  str.toCharArray(buf, str_int);
  return buf;
  free(buf);
}

Why can't I allocate memory to buf, return its content and then free the memory allocation?

I have seen some people do:

x = myfunc();
free(x);

So, they basically use the function and use free() outside the function.
But then it would imply that I have to use free() everytime I used the function.
I do not seem to have to do that with any of the contributed Arduino libraries (or do I?).

I started to read about the usage of malloc inside functions and then things started getting weird with people seemingly not agreeing about the proper way to do it (double pass functions, etc...). This thread is such an example: malloc thread

At this point I am getting really confused. So what would be the proper way to do it in my case?

Thanks.

jg1xmv:
Thanks to both of you for the floating pointer / free() comments.

Currently, doing it wrong looks like this:

char *myfunc(String str) {

int str_int = str.length() + 1;
  char *buf;
  buf = (char *) malloc(sizeof(char) * (str_int + 1));
  str.toCharArray(buf, str_int);
  return buf;
  free(buf);
}




Why can't I allocate memory to buf, return its content and then free the memory allocation?

I have seen some people do:


x = myfunc();
free(x);




So, they basically use the function and use free() outside the function.
But then it would imply that I have to use free() everytime I used the function.
I do not seem to have to do that with any of the contributed Arduino libraries (or do I?).

I started to read about the usage of malloc inside functions and then things started getting weird with people seemingly not agreeing about the proper way to do it (double path functions, etc...). This thread is such an example: [malloc thread](https://www.reddit.com/r/C_Programming/comments/2wu0i5/is_it_better_to_malloc_inside_a_function_or/)

At this point I am getting really confused. So what would be the proper way to do it in my case?

Thanks.

My comment was wrong and has been corrected.

Your way of doing it is fine as long as you remember to free the memory.

The proper C way to deal with this situation is to pass an already allocated memory to your function and fill that memory.

Thanks for the clarification arduino_new. You mean which is ok?

1st case:

char *myfunc(String str) {
  int str_int = str.length() + 1;
  char *buf;
  buf = (char *) malloc(sizeof(char) * (str_int + 1));
  str.toCharArray(buf, str_int);
  return buf;
  free(buf);
}

2nd case:

x = myfunc();
free(x);

or a combo 1st case + 2nd case?

UKHeliBob is of the opinion that free() inside the function will not be executed, so I am just trying to clarify things.

For all readers, sorry the "class" thread has morphed into a "malloc inside functions" thread but this is very interesting stuff.

1st case is wrong. No code after the return is ever executed as previously pointed out

Thanks UKHeliBob, I understand. Based on this, I have additional questions:

Does it mean I am supposed to use free() everytime I use a function to pass something to a variable outside the function? I mean, I don't even know if malloc was used inside the function I am using (unless I have access to and check the code for everything single one of them).

Is there a way that allows to perform dynamic memory allocation inside the function without having to use free() outside of it everytime I use the function?

Or overall, what is the easiest / cleanest way of doing things (understanding that easy and clean may be mutually exclusive in this case).

How do you code your functions and manage the memory usage resulting from them UKHeliBob?

How do you code your functions and manage the memory usage resulting from them UKHeliBob?

Using local variables wherever possible and by passing variables by reference instead of value is a good start

ok thanks, I'll dig into this and see if I can come-up with something more elegant by myself.