0

Looking for answers to this question did reveal a few replies, which made not much sense to me as a beginning C programmer.

I program Arduinos, most of which are connected to a network, and most of which include a temperature sensor to derive a MAC address from. They all publish messages via MQTT.

My .cpp file looks like this:

/*
Some description
*/

/* --------------- Configuration file --------------------------------------- */
#ifndef CONFIG_H
#   include "config.h"
#endif

/* --------------- Libraries ------------------------------------------------ */
#include <Arduino.h>                            // basic Arduino definitions
#include <avr/wdt.h>                            // watch dog
#include <stdbool.h>                            // boolean definition
#include <SPI.h>                                // Serial Peripheral Interface Bus
#include <Ethernet.h>                           // Ethernet library for EtherShield
#include <PubSubClient.h>                       // MQTT client library
#include <OneWire.h>                            // OneWire library for Dallas DSB etc.

// ----- global variables
...

/* --------------- Instantiate global objects ------------------------------- */
EthernetClient ethernet_client;                 // Ethernet
PubSubClient mqtt_client (ethernet_client);     // instantiate MQTT with ethernet_client


/* --------------- Prototypes ----------------------------------------------- */
// common static code modules
void mac_address_build (uint8_t pin);
void ethernet_connection_maintain ();
void bicolour_led_set (uint8_t ledState);
char *deblank (char *str);

void mac_address_publish ();
void message_publish (const char *topic, const char *msg);
void error_publish (uint8_t error_type, char *error_msg);

void temperature_collect ();
float temperature_get (uint8_t pin);
float temperature_validate (uint8_t pin, float temp_sensed);
void temperature_publish (float temp);

// common code but modify as required
bool b_connected_to_broker ();
void mqtt_call_back (char *topic, byte *payload, uint16_t length);

// controller specific functions
void meter_pulse_counter_isr();
void meter_values_calculate();
void meter_values_publish (float litres_total);
void soil_permittivity_measure();

/* --------------- Function declarations ------------------------------------ */
// as prototype above

void setup ()
{
}

void loop ()
{
}

I thought that simply putting the "common static code modules" and put them into a standard_functions.cpp, and include it after the config.h, like so:

/* --------------- Standard functions --------------------------------------- */
#ifndef STD_FUNCTIONS
#define STD_FUNCTIONS
#   include "standard_functions.cpp"
#endif

However, I then get error messages that the identifiers are not declared.

What I'd like to achieve is to have these common modules in a separate file, which I include in main.cpp, so that I can maintain a single include file for all other programs I might write.

I read: Should I use #include in headers? How to split this into header and source files? How to split code into multiple files

... which I could not apply to my 'problem'. One even suggesting I need to create another .h file (in addition to the .cpp).

As for terminology, I assume .h stands for header file, but which can have any other name as long as it ends in .h?!

Is it feasible, common practice to have my 'standard_functions' contained in one file (.cpp or .h) or do I need a standard_functions.h and .cpp? What is in each? When I create the standard_function.cpp and put the functions in I get some 70 identifier not defined messages. However, when I rename the standard_functions.cpp to .h I get only 1 error messages, which seems to indicate this to be the better name. The error is variable or field 'mac_address_build' declared void; though the code compiles error free if all is on one file. However, when moving this function to second place, more errors pop up about unidentified identifiers.

I split the files various ways and the error messages kept piling up. So yes, I didn't 'get it'.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
MaxG
  • 187
  • 3
  • 11
  • 2
    You seem to be asking about C++, which is not the same as C. I suggest tweaking the title and tags. – resiliware Sep 25 '20 at 00:34
  • 2
    You might have circular dependencies requiring forward declaration. This is pretty common. Please avoid including `.cpp` files. The intention is for CPP source to be compiled into an object file, and for headers to provide the types and interfaces required to reference the stuff in that object file. Later on, the linker combines all your object files together. In short, the header should provide function and type declarations, and the source file should provide the actual implementation. – paddy Sep 25 '20 at 00:48
  • Your include guards are backwards. They belong in the included file, not around the `#include` directive. Also, consider `#pragma once` as an alternative. – bitmask Sep 25 '20 at 01:01
  • Well, I appreciate all the wisdom, but I maybe too thick to make sense of it... circular dependency, forward declaration... as for type declarations, do I have to define uint_t and all? I wouldn't find this helpful as in simplifying things?! I reckon the guards are the #ifdef; so if this case they go into the file to be included?! – MaxG Sep 25 '20 at 02:24
  • [circular dependency](https://en.wikipedia.org/wiki/Circular_dependency) and [forward declaration](https://en.wikipedia.org/wiki/Forward_declaration) are even mentioned in Wikipedia. These are basic issues of C++ (and C). So, googling it, you may find tutorials and other stuff where it is explained. - In general: C++ is _not_ something which is intuitive and can be learned by "clicking (or swiping) around" a bit. I'm afraid you have to read a book (or online articles) to learn how to do things right (or to accept that weird things happen in your programs where you don't know why). – Scheff's Cat Sep 25 '20 at 06:32
  • I forgot the [header guards](https://en.wikipedia.org/wiki/Include_guard)... ;-) – Scheff's Cat Sep 25 '20 at 06:35
  • I figured it out by watching a few Youtubes; thanks. – MaxG Sep 25 '20 at 10:17

0 Answers0