Pages: [1] 2   Go Down
Author Topic: undefined references and static keyword  (Read 2424 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: May 19, 2008, 06:16:04 am by tigrezno » Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
}
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mmm i'll try later, thanks!
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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() {
}
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 9
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Wuppertal/Germany
Offline Offline
God Member
*****
Karma: 1
Posts: 895
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

New Zealand
Offline Offline
God Member
*****
Karma: 0
Posts: 999
Arduino pebbles
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Wuppertal/Germany
Offline Offline
God Member
*****
Karma: 1
Posts: 895
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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



« Last Edit: May 20, 2008, 04:46:47 am by wayoda » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley
Logged

Wuppertal/Germany
Offline Offline
God Member
*****
Karma: 1
Posts: 895
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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    smiley-wink

Eberhard
Logged

Pages: [1] 2   Go Up
Jump to: