Notifications
Clear all

Arduino .h file vs .h and .cpp files

21 Posts
5 Users
4 Likes
1,087 Views
mr.meeseeks
(@mr-meeseeks)
Livingrimoire coder
Joined: 9 months ago
Posts: 19
Topic starter  

what are the benefits(if any) of using both .h and .cpp files for an Arduino class versus placing all the code inside

just a .h file?

Team Fuki


   
Quote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2535
 

Posted by: @mr-meeseeks

what are the benefits(if any) of using both .h and .cpp files for an Arduino class versus placing all the code inside

just a .h file?

For one major thing, you don't have to dig your way through all the code to discover the data and function declarations.

Also, remember that you need to include the .h file to allow other components to recognize the data and interface to functionality provided by the code. If you added the code into the .h file then you'd potentially have multiple copies of the code itself which would bloat your application and confuse the compiler/builder.

Anything seems possible when you don't know what you're talking about.


   
Inq and mr.meeseeks reacted
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 

Posted by: @mr-meeseeks

what are the benefits(if any) of using both .h and .cpp files for an Arduino class versus placing all the code inside

just a .h file?

Some compilers treat *.h coding (as in having the entire function in the .h) as in-line.  I couldn't say what the Arduino compiler does for Arduino and for ESP, it uses GCC (GNu C) compiler.  The point being if it is in-lined and used one hundred times in other functions, you have the binary code is implement 100 times bloating your MPU's limited space.  If it is separated in a CPP file, it is implemented once and the 100 calls jump to the code.  Now... that concept (tradition) might be ancient history as optimizing compilers might be smart enough pull the 100 instances.  But, then again there are size optimizations and speed optimizations.  I have no idea what Arduino IDE uses for optimization.  I know using ESP32 on VSCode gives me the option to optimize for speed or size.

 

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 

Posted by: @will

If you added the code into the .h file then you'd potentially have multiple copies of the code itself which would bloat your application and confuse the compiler/builder.

Oops!  You already said that.  

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
(@codeslinger)
Member
Joined: 4 years ago
Posts: 30
 

Putting executable code into the .h file is a bad idea and not best practice.  Firstly, as mentioned already, the code is compiled every time the .h file is included.  Secondly, if you need to change the logic then you need to recompile everything that includes that header (.h) file.  If it is in the .cpp, then only that need to be compiled and then the executable rebuilt.  

Think of the header file as a contract between the module and the world.  The only things that should be there are those that are necessary to interact with the module.  Among these are, data types, structures, functions, and constants.  If it is only needed by the internal logic of the module, it should be declared within the .cpp file and not in the header.  The less that is included in the header, the less time it takes to compile the entire program.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7017
 

@inq @codeslinger Maybe I misunderstand. I have a module of code that outputs debugging messages on both the Serial port and an MQTT client. Since I don't want to see that code in every sketch I make, I keep it in a h file and include it once near the top of the sketch. Does that have the problem @inq mentions or @codeslinger ? Also, how else can I implement a common module like this?

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 

Posted by: @zander

@inq @codeslinger Maybe I misunderstand. I have a module of code that outputs debugging messages on both the Serial port and an MQTT client. Since I don't want to see that code in every sketch I make, I keep it in a h file and include it once near the top of the sketch. Does that have the problem @inq mentions or @codeslinger ? Also, how else can I implement a common module like this?

If your commonly used function is in a C/CPP file, there is no issue.  If it is in the .H file and you only call it once in every one of your projects, there is no issue.  The only issue is if it is called multiple times in the same project.  If the code is in the *.h file, its almost the same as a #define... it is in-lined on every calling.  So if you have a function say... of 100 lines in a *.h, AND it is called multiple times within the same project, that code is inserted at every calling. 

I might have to make up an example and see how good a job of optimizing that scenario the Arduino compiler handles.  And then... the ESP8266/ESP32 compiler under Arduino IDE and then under VSCode.

Out of Inquisitiveness of course. 😉 

 

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2535
 

Posted by: @zander

Since I don't want to see that code in every sketch I make, I keep it in a h file and include it once near the top of the sketch. Does that have the problem @inq mentions or @codeslinger ? Also, how else can I implement a common module like this?

I think the ideal solution would be to implement it as a library with a .h and separate .cpp file. That is, after all, the purpose of libraries.

 

Anything seems possible when you don't know what you're talking about.


   
Inq reacted
ReplyQuote
(@codeslinger)
Member
Joined: 4 years ago
Posts: 30
 

@inq There is another reason to have only the minimum amount to support the interface in the .h file instead of the entire implementation. When you put everything in the .h file, all of the symbols defined there are in potential conflict with those in the including file.  


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 

Posted by: @will

I think the ideal solution would be to implement it as a library with a .h and separate .cpp file. That is, after all, the purpose of libraries.

I completely agree.  Putting a commonly used routine/class in a library... in the library folder is by far the best solution!  If you do it properly, it will be listed under the menu item Sketch / Include Library... clicking will automatically put it in your Sketch.

 

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7017
 

@inq I am 100% sure you are talking about something different than what I am doing. I have a module called LOG that I call from various points in a sketch. The only difference as far as I know is that instead of copying code I use all the time into every sketch I write, I simply save it in a .h file and then #include it near the beginning of the sketch.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 

Posted by: @codeslinger

@inq There is another reason to have only the minimum amount to support the interface in the .h file instead of the entire implementation. When you put everything in the .h file, all of the symbols defined there are in potential conflict with those in the including file.  

I'm not quite sure I'm getting the nuance here.  Can you give me an example?  I only create C++ libraries so everything is encapsulated.  I also, always use separate CPP files.  The only code I put in the *.h file (being in-lined) are things like getters/setters:

class widget
{
private:
   int _someVariable;

public:
  int getSomeVariable() { return _someVariable; }
  void setSomeVariable(int value)
  {
       // validate as necessary
      _someVariable = value;
      // kick-off any optional procedures
   }

...

};

 

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 

Posted by: @zander

@inq I am 100% sure you are talking about something different than what I am doing. I have a module called LOG that I call from various points in a sketch. The only difference as far as I know is that instead of copying code I use all the time into every sketch I write, I simply save it in a .h file and then #include it near the beginning of the sketch.

Frankly, in your case, I wouldn't worry about it.  It's on the same level as your signature.  #define versus const.

If your LOG function is entirely written in the *.h file, then every time you call it in a sketch, the compiler will create the binary code for that entire function and place it at each and every instance of you calling it.  IF however, you put the code inside a *.c or *.cpp file and simply declare the prototype in the header file, the compiler will ONLY create one instance of it in your binary code and every place you call it will simply JUMP to it.

One version is faster and takes up more binary space.  The other is slightly slower, but more compact.

 

 

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7017
 

@will I think I am confusing you. Let me explain it a different way. If I always code the same 10 lines of code at the beginning of every sketch, then I take those 10 lines and put them inside a .h file and now the 10 lines are replaced by one. It's unusual, but the generated code is identical.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7017
 

@inq I am 99.99999% sure you are wrong, but I will test it. By the time the compiler sees the code, the source file looks the same as before I extracted the 10 lines into a .h file that the pre-processor has now sucked in.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Page 1 / 2