undefined references and static keyword

Hi, i'm just curious about this error:

o: In function updateSystemLED()': undefined reference to __cxa_guard_acquire'

void updateSystemLED() {
static Alarm x;
}

If i drop the static keyword, it works. This only happens when i declare static a selfmade class object, it will work with int, char, and so on.

Do you know why?

Note sure what you mean by: “This only happens when i declare static a selfmade class object”

If updateSystemLED() is a method in a non-static class you are making, can you avoid making the Alarm variable static by declaring it as a private property.

It would be a little easer to see why you want to declare Alarm static if you showed the code in updateSystemLED that referenced the Alarm variable.

no, updateSystemLED() is a function out of the class. I'm just declaring an Alarm object as static.

The problem happened on two different linux distros so it must be something with the avr compiler i think.

If I declare the same object without "static", it just works. But i need to declare it static for what i need.

[mem] can you try it with the Servo library for example?

void example() {
static Servo s;
}

If it won't happen, may be it's related to my Alarm library. I'm now at work and can't try it right now.

You may not be calling your constructor, have you tried something like the following:

void updateSystemLED() {
static Alarm x; // Alarm is a class and x is the reference to the class
x = Alarm(); //instantiate x as a static instance of the Alarm class
}

mmm i'll try later, thanks!

mem can you try this simple code? it repeats the compile error...

class Alarm {
      private:
            unsigned long time;
            
      public:
            Alarm();
            Alarm(unsigned long t);
            ~Alarm();
            void set(unsigned long t);
            void unset();
            boolean checked();
};

Alarm::Alarm() {
      time = 0;
}

Alarm::Alarm(unsigned long t) {
      time = millis() + t;
}

Alarm::~Alarm() {
      time = 0;
}

void Alarm::set(unsigned long t) {
      time = millis() + t;
}

void Alarm::unset() {
      time = 0;
}

boolean Alarm::checked() {
      if ((!time) || (time > millis()))
            return false;
      else
            return true;
}

void example() {
  static Alarm x;
}

void setup() {
}

void loop() {
}

I get the same error.

You can eliminate the error by moving the declaration
static Alarm x ;
to outside the example function.

If this is not what you want, could you say a little more about what you are trying to do.

well, i wanted it to be inside the function, but looks like a compiler related error, isn't it?
i can use it outside, no problem, but it's an interesting bug.

It is a strange bug. The avr-g++ compiler only supports some of C++; this might just be something it doesn't support. (In particular, there's no C++ runtime support, but I'm not sure whether or why this would qualify as that.)

Hi,
I'm not too experienced with this, but I don't think this is a valid c++ construct.

I also don't know what you want to achieve with creating a static class instance that is local to a function.

If you goal is to create only a single instance of class Alarm you can declare everything inside the class static (data and methods). (Arduino-)Example for this : Arduino Playground - FrequencyTimer2

Or search the web for "c++ singleton pattern" for an alternative approach...

Eberhard

I don't want singleton, since it allows only 1 instance for each class.
I can declare many alarms, for example: Alarm x,y,z;

In my code i declare an Alarm as static instead of global, because it will be used only on that function and i want it to be persistent. But it looks like not working at all.

o: In function updateSystemLED()': undefined reference to __cxa_guard_acquire'

This seems to be related to unimplemented C++ functionality.

See this C++ and avrgcc thread which alludes to this issue and includes code to "fix" the issue.

There appears to be an additional possible '__cxa_guard_acquire' error explanation.

--Phil.

Hi,

I don't want singleton, since it allows only 1 instance for each class.
I can declare many alarms, for example: Alarm x,y,z;

In my code i declare an Alarm as static instead of global, because it will be used only on that function and i want it to be persistent. But it looks like not working at all.

In C++ it is not possible to declare an Object private to a method and persistent at the same time. What you want is a instance of an Alarm-Object that is private to some other kind of Object that raises the Alarm.

class Alarm {
        private:
                unsigned long time;
                
        public:
                Alarm();
                Alarm(unsigned long t);
                ~Alarm();
                void set(unsigned long t);
                void unset();
                boolean checked();
};

Alarm::Alarm() {
        time = 0;
}

Alarm::Alarm(unsigned long t) {
        time = millis() + t;
}

Alarm::~Alarm() {
        time = 0;
}

void Alarm::set(unsigned long t) {
        time = millis() + t;
}

void Alarm::unset() {
        time = 0;
}

boolean Alarm::checked() {
        if ((!time) || (time > millis()))
                return false;
        else
                return true;
}

class AlarmControl {
  private :
    Alarm x; 
    
  public :
     AlarmControl();
     void setTheAlarm();
};

AlarmControl::AlarmControl() {
   x=Alarm();
}

void AlarmControl::setTheAlarm() {
  x.set(1000);
}

AlarmControl ac=AlarmControl();


void setup() {
  ac.setTheAlarm();
}

void loop() {
}

Now an AlarmControl can access its internal Alarm but it is not visible from the rest of the code.

So this is not a compiler-bug at all, its simply illegal to declare a static instance of a class that way.
[edit]
not a bug in the sense of : I enter correct code but the compiler refuses to compile it.
Would be nice to have the compiler return "you can't do that!"
[/edit]

Eberhard

interesting, the solution is a bit "ugly" since i need more classes to do a simple thing, but i'll stick with an object outside of the method.

thanks for solving this issue :slight_smile:

Hi,
I think the "ugliness factor" stems from the fact that code being just an example.
Just imagine that AlarmControl, has many more features like monitoring a multitude of analog values and raising the private Alarm on certain conditions.

On the other hand for a serious "C"-programmer everything that is introduced by the keyword "class" followed by a curly brace is ultimately ugly in itself :wink:

Eberhard

Follower, sorry, i didn't see your post. Your correct, it's a missing feature of avr-g++.

wayoda: yes, i know some people think c++ is ugly itself. I'm a ruby-boy but i've used C and C++ for years too, and i've seen that programmer wars are too common. Thanks for your support!