Go Down

Topic: undefined references and static keyword (Read 3597 times) previous topic - next topic

tigrezno

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?

mem

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.

tigrezno

#2
May 19, 2008, 01:13 pm Last Edit: May 19, 2008, 01:16 pm by tigrezno Reason: 1
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.

mem

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
}

tigrezno


tigrezno

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

Code: [Select]
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() {
}

mem

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.

tigrezno

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.

mellis

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.)

wayoda

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 : http://www.arduino.cc/playground/Code/FrequencyTimer2

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

Eberhard

tigrezno

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.

follower

Quote
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.

wayoda

#12
May 20, 2008, 11:44 am Last Edit: May 20, 2008, 11:46 am by wayoda Reason: 1
Hi,
Quote
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.
Code: [Select]

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




tigrezno

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 :)

wayoda

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    ;)

Eberhard

Go Up