Error when using inline methods in C++ classes: Undefined Reference to

Asked

Viewed 129 times

0

I’m optimizing part of my code where some methods that are called loop very often I’m passing them to inline, but while doing so I’m getting the following error messages:

And I’m getting the following mistake:

In file included from CycloTracker.hpp:15:0,
                 from CycloTracker.cpp:3:
ObjectTracker.hpp:45:14: warning: inline function ‘void ObjectTracker::PrintLeftPartial(cv::Mat&)’ used but never defined
  inline void PrintLeftPartial(cv::Mat &frame);
              ^
ObjectTracker.hpp:46:14: warning: inline function ‘void ObjectTracker::PrintRightPartial(cv::Mat&)’ used but never defined
  inline void PrintRightPartial(cv::Mat &frame);
              ^
ObjectTracker.hpp:43:14: warning: inline function ‘void ObjectTracker::PrintLeftPartial(cv::Mat&, cv::Point)’ used but never defined
  inline void PrintLeftPartial(cv::Mat &frame, cv::Point pt);
              ^
ObjectTracker.hpp:44:14: warning: inline function ‘void ObjectTracker::PrintRightPartial(cv::Mat&, cv::Point)’ used but never defined
  inline void PrintRightPartial(cv::Mat &frame, cv::Point pt);
              ^
....
CycloTracker.o: In function `CycloTracker::processFrames()':
/home/fa/Workspace/contadordeciclistas/CycloTracker.cpp:64: undefined reference to `ObjectTracker::PrintLeftPartial(cv::Mat&)'
/home/fa/Workspace/contadordeciclistas/CycloTracker.cpp:65: undefined reference to `ObjectTracker::PrintRightPartial(cv::Mat&)'
/home/fa/Workspace/contadordeciclistas/CycloTracker.cpp:104: undefined reference to `ObjectTracker::PrintLeftPartial(cv::Mat&, cv::Point_<int>)'
/home/fa/Workspace/contadordeciclistas/CycloTracker.cpp:105: undefined reference to `ObjectTracker::PrintRightPartial(cv::Mat&, cv::Point_<int>)'
collect2: error: ld returned 1 exit status
Makefile:56: recipe for target 'all' failed
make: *** [all] Error 1

I already compiled all the files thinking it could be dirt in the code, already compiled, but it doesn’t solve.

How should I proceed to use methods inlinein classes?

Below are the codes that have been transformed into inline:

inline void ObjectTracker::PrintRightPartial(cv::Mat &frame, cv::Point pt) {
    char id[10];
    sprintf(id, ">%02d", object_counter->GetLTRPoints());
    cv::putText(frame, std::string(id), pt, CV_FONT_HERSHEY_PLAIN, 3,
            cv::Scalar(0, 0, 0), 5, CV_AA);
    cv::putText(frame, std::string(id), pt, CV_FONT_HERSHEY_PLAIN, 3,
            cv::Scalar(0, 255, 255), 3, CV_AA);
}

inline void ObjectTracker::PrintLeftPartial(cv::Mat &frame, cv::Point pt) {
    char id[10];
    sprintf(id, "<%02d", object_counter->GetRTLPoints());
    cv::putText(frame, std::string(id), pt, CV_FONT_HERSHEY_PLAIN, 3,
            cv::Scalar(0, 0, 0), 5, CV_AA);
    cv::putText(frame, std::string(id), pt, CV_FONT_HERSHEY_PLAIN, 3,
            cv::Scalar(0, 255, 255), 3, CV_AA);
}

inline void ObjectTracker::PrintLeftPartial(cv::Mat &frame) {
    PrintLeftPartial(frame, config->GetCounterPos(0));
}

inline void ObjectTracker::PrintRightPartial(cv::Mat &frame) {
    PrintRightPartial(frame, config->GetCounterPos(1));
}

Calls of the above methods:

...

ObjectTracker ot(config, 30, 50, config->getInterestArea());

...

do {

        *cap >> frame;      // captura um novo frame e processa imediatamente
        full = frame.clone();
...
        ot.PrintLeftPartial(full);
        ot.PrintRightPartial(full);
...
    } while (char(key) != char(27));

So I tried to suck the code as suggested here: Iterated inline functions

But it didn’t work by generating the following errors:

In file included from CycloTracker.hpp:15:0,
                 from CycloTracker.cpp:3:
ObjectTracker.hpp:46:8: warning: always_inline function might not be inlinable [-Wattributes]
   void PrintRightPartial(cv::Mat &frame)__attribute__((always_inline));
        ^
ObjectTracker.hpp:45:8: warning: always_inline function might not be inlinable [-Wattributes]
   void PrintLeftPartial(cv::Mat &frame)__attribute__((always_inline));
        ^
ObjectTracker.hpp: In member function ‘void CycloTracker::processFrames()’:
ObjectTracker.hpp:45:8: error: inlining failed in call to always_inline ‘void ObjectTracker::PrintLeftPartial(cv::Mat&)’: function body not available
CycloTracker.cpp:64:28: error: called from here
   ot.PrintLeftPartial(full);
                            ^
In file included from CycloTracker.hpp:15:0,
                 from CycloTracker.cpp:3:
ObjectTracker.hpp:46:8: error: inlining failed in call to always_inline ‘void ObjectTracker::PrintRightPartial(cv::Mat&)’: function body not available
   void PrintRightPartial(cv::Mat &frame)__attribute__((always_inline));
        ^
CycloTracker.cpp:65:29: error: called from here
   ot.PrintRightPartial(full);
                             ^
Makefile:65: recipe for target 'CycloTracker.o' failed
make: *** [CycloTracker.o] Error 1

The code was as follows in what I changed:

 void PrintLeftPartial(cv::Mat &frame, cv::Point pt)__attribute__((always_inline));
 void PrintRightPartial(cv::Mat &frame, cv::Point pt)__attribute__((always_inline));
 void PrintLeftPartial(cv::Mat &frame)__attribute__((always_inline));
 void PrintRightPartial(cv::Mat &frame)__attribute__((always_inline));
  • Which file does the code snippet you posted belong to? Show the code for these methods in both the header and source file.

  • Hello @aslg this code will be opensource, but I am going to release it publicly when everything is set, if that is the case send me your email that I give you access to the repository in Gitbucket. I am doing this so that all code is well structured before releasing and avoid too many unnecessary updates publicly.

  • The question is not open source, I just wanted to confirm that the definition of the methods was done in . cpp and the statement in .h. What in the case of inline functions is not correct. But André has already answered.

1 answer

2

The functions declared with inline need to be defined (that is, they must possess a body) in the same Translation Unit where they are used. A Translation Unit is a source file (.cpp) and all the headers (.hpp) which he includes.

In practice, when declaring a function inline in a header, the implementation of it must be together. It can be either together with the statement or more below.

This applies to free functions or functions that are class members (methods).

Example:

inline void function1();  // declarada aqui, definida abaixo
inline void function2() {  // declarada e definida aqui
    // ...
}

class A {
public:
    inline void method1();  // declarado aqui, definido abaixo
    inline void method2() {  // declarado e definido aqui
        // ...
    }
};

void function1() {
    // ...
}

void A::method1() {
    // ...
}
  • Thanks André, I am not very adept to put the implementation of the codes together with the class declaration and their signatures, even more in the header file. How can I solve situations like this where I need the algorithm to be optimized avoiding the stack as much as possible? i have been trying to reduce the maximum number of parameters in the functions by parameterizing the creation of classes and creating set/get functions to update such parameters only when really needed.

  • @Delfino, putting implementation on headers has its drawbacks, but if you want to avoid making a function call, the compiler needs to see the implementation when compiling the call. Note that inline does not necessarily reduce the size, reduce stack usage, or make the program faster. Before doing micro-optimizations like these, I suggest analyzing the performance of the program to see where the bottlenecks really are, because it may be that it’s only getting worse.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.