trying to make a library "multiple definition of '#var'

Hello I am new to arduino programming
and After I read the create your library-tutorial I thought that I could make one.

So I took made all the prototypes of the functions of an already working sketch and
create a File.h, and removed the code setup() and loop() and saved as File.cpp

Saved both on Arduino_PATH/libraries/File/

imported it and by the IDE, and all variables that I used (global variables)
got this message:

File\File.cpp.o:(.data.a+0x0): multiple definition of `#var'
_7seg.cpp.o:(.data.a+0x0): first defined here

and then I tried to define them as extern to see, if it would help but all I got was more warnings..

Arduino_PATH\libraries\File/File.h:23: warning: 'g' initialized and declared 'extern'

File.cpp:
#include "Arduino.h"
#include "File.h"

File.h:
#ifndef File_H
#define File_H

#include <Arduino.h>
extern int a = 7;
extern int b = 6;
extern int c = 5;

#endif

Sketch:
#include <File.h>
setup(){
#define a lot of things
}
loop(){
#do something
}

You cannot do anything in a .h file that allocates memory -- essentially, you may declare functions (but not define them), declare data as extern (but not as non-extern) and declare classes (and structs and enums and unions...)

okay:

// foo.h
extern int bar;
void f();
class foobar {
public:
  foo();
};

not okay:

int var;
void func() {
  var++;
}

Note that if a variable is declared extern, it must be defined somewhere else. "extern" means "the variable is defined somewhere else" so you'll just confuse the linker if you say it's somewhere else and then not have it at all. This also means you can't give a value to them because that's a definition, not a declaration.

WizenedEE:
You cannot do anything in a .h file that allocates memory -- essentially, you may declare functions (but not define them), declare data as extern (but not as non-extern) and declare classes (and structs and enums and unions...)

okay:

// foo.h

extern int bar;
void f();
class foobar {
public:
  foo();
};




not okay:


int var;
void func() {
  var++;
}




Note that if a variable is declared extern, it must be defined somewhere else. "extern" means "the variable is defined somewhere else" so you'll just confuse the linker if you say it's somewhere else and then not have it at all. This also means you can't give a value to them because that's a definition, not a declaration.

Thank you very much for this information, it worked perfectly!

I have just one more question regarding libraries :
Is it possible to just give compile it and send it to my friends in order to avoid them looking in the source (cpp) ?

Like a folder in Libraries with a File.h and File.o instead of File.cpp?

I have just one more question regarding libraries :
Is it possible to just give compile it and send it to my friends in order to avoid them looking in the source (cpp) ?

Like a folder in Libraries with a File.h and File.o instead of File.cpp?

Not easily, and not recommended (we're all about open source). All of my arduino stuff is here: https://github.com/WizenedEE/arduino

essentially, you may declare functions (but not define them)

That is not true. It is possible to implement functions in a header file. I do it all the time for get/set type functions that set/get a private field's contents.

extern int a = 7;
extern int b = 6;
extern int c = 5;

Think about the scope for abuse here.
Another file could quite legitimately have

extern int a = 5;
extern int b = 6;
extern int c = 7;

Which is why you got the warning.

Which set of initialisers is the correct one?

Another file could quite legitimately have

Which is a good argument for NOT using one letter variable names. Especially for global variables.

For loop indices, I like one letter variable names, like i. For EVERYTHING else, longer is better. By orders of magnitude. What the hell do a, b, and c mean, anyway?

Which is a good argument for NOT using one letter variable names.

It doesn't matter if the variable name is "a" or "antidisestablishmentarianismInitiator", the scope (pardon the pun) for confusion is still there: extern int antidisestablishmentarianismInitiator = 12; in one file and extern int antidisestablishmentarianismInitiator = 11; in another is going to confuse. Only the implicit global should be initialised.

It doesn't matter if the variable name is "a" or "antidisestablishmentarianismInitiator", the scope (pardon the pun) for confusion is still there:

I think the likelihood for duplication of names goes down, when the names are longer, but, of course you are right, in that the potential for problems still exists.

Only the implicit global should be initialised.

True, but I would describe the real variable as actual, rather than implicit. The extern statement says that the variable is defined in another file (the actual definition) but needs to be used in this file. The variable, then, should NOT be initialized in this header file. Initializing it in the source file that goes with this header file is another matter. I still wouldn't.