Global variable declared but "not declared in this scope" error

Hi,

I'm making some changes in the Time.h libraries to create a counter for the number of sync failures. To do that, I declare a global variable right after the libraries like this:

...
#include <Time.h>
int SyncErrors = 0;
...

The function to update the time is called now() and it's declared inside Time.cpp.

time_t now(){
  while( millis() - prevMillis >= 1000){      
    sysTime++;
    prevMillis += 1000;	
#ifdef TIME_DRIFT_INFO
    sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift     
#endif	
  }
  if(nextSyncTime <= sysTime){    // If the time in the Arduino is bigger than the next update time
      if(getTimePtr != 0){             // If the pointer to the sync time provider is set
	  time_t t = getTimePtr();  // Execute the sync function
      if( t != 0 ){			      // If the result is not zero
        if( t > 1342953605 ){	      // If the result makes sense instead of year 1970
          setTime(t);		      // Set the time
          Serial.print("Time Updated "); 
        }
        else{				      // If the time has never been set, it will start in 1970
          if( Status == timeNotSet )
            setTime(t);
        }
      }
      else{
        Status = (Status == timeNotSet) ?  timeNotSet : timeNeedsSync;
        if ( Status == timeNeedsSync ){
          Serial.println("Sync failed");
          SyncErrors++;
        }
      }
    }
  }  
  return sysTime;
}

When trying to compile I get the error:

Time.cpp: In function 'time_t now()':
Time.cpp:268: error: 'SyncErrors' was not declared in this scope

It has something to do with the scope of the variables inside the libraries, but I thought that global variables can be used everywhere.

Any ideas why this is happening?

Global variables can be used anywhere within the file in which they are defined. If you want to reference them within other files then you have to tell those files of the variable's existance by declaring them as extern in the file you want to use them in.

extern int syncErrors;

Thanks, I was going to post the answer myself. I just found it five minutes after my message, although I've been searching for it for hours before... Murphy's law!

As a hobbiest programmer I learn lots by reading these questions, trying to come up with an answer, and then checking back to see if I was right and, as is often the case, why I was wrong.

I have a question about this. Wouldn't it be bad mojo to have a library that is expecting a variable to be declared external to it? Shouldn't that variable be declared in the library?

My instinct tells me to declare a private variable to the class and then add a function to the class that returns the value.

Always trying to learn more. Thanks.

Ideally yes, the variable should be defined in the library, not the main sketch.

Even better, the variable should be entirely contained within the library and modified using function calls that the library can provide. That also gives you the ability to implement bounds checking as well.

I agree with majenko. The library, if it is appropriate for the sketch to change the value, should provide the means for the sketch to do so.

In the case of the Time library, I can see no compelling reason for the library to not expose the syncErrors value. On the other hand, I can see no benefit in knowing how many times the sync failed, without knowing the time frame in which those failures occurred.

3 sync failures over the course of 10 minutes is one thing. 3 sync failures over the course of 10 years is something else.

Thanks for your comments!

I've never worked with libraries and classes before so I have only a rough idea of what to do and where to achieve what I want.

Jimmy60 and majenko are right, I should add a variable to the library and access it from the sketch using functions instead of declaring it as global and extern. In this particular case, reading through the Time library (with Notepad++ instead of Wordpad this time, what a difference it makes!!), I found the function called timeStatus() that returns the Status, and I can use it from the sketch to check whether the time needs sync or not.

PaulS is right too, I just realised that I need a time interval for the number of sync failures, not just an ammount.