LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 08-31-2017, 04:21 PM   #1
selfprogrammed
Member
 
Registered: Jan 2010
Location: Minnesota, USA
Distribution: Slackware 13.37, 14.2, 15.0
Posts: 635

Rep: Reputation: 154Reputation: 154
Question OpenThreads cannot see its own enum declaration


Compiler g++ 5.3.0, on Linux 4.4.38.

I am trying to compile SimGear 3.4.0, which uses OpenSceneGraph 3.2.1.
The following header (in /usr/include/OpenThreads/ReentrantMutex) fails
with a message "MUTEX_RECURSIVE" has not been declared.

Code:
#include <OpenThreads/Thread>
#include <OpenThreads/Mutex>
#include <OpenThreads/ScopedLock>

namespace OpenThreads {

class ReentrantMutex : public OpenThreads::Mutex
{
    public:

        ReentrantMutex():
            Mutex(MUTEX_RECURSIVE) {}

};

}

I have tried changing the include file line to:

Code:
    Mutex(OpenThreads::Mutex::MutexType::MUTEX_RECURSIVE) {}
but still get an error that MutexType has not been declared.


The relevant part of the Mutex file, which shows that the
MUTEX_RECURSIVE is declared in an enum, in the Mutex class.

Code:
#include <OpenThreads/Exports>

namespace OpenThreads {

/**
 *  @class Mutex
 *  @brief  This class provides an object-oriented thread mutex interface.
 */
class OPENTHREAD_EXPORT_DIRECTIVE Mutex {

    friend class Condition;

public:

    enum MutexType
    {
        MUTEX_NORMAL,
        MUTEX_RECURSIVE
    };

    /**
     *  Constructor
     */
    Mutex(MutexType type=MUTEX_NORMAL);

Is this a bug in the compiler, some new restriction for C++,
or some weird C++ namespace problem ??

I have been programming since the 1980's but have only been
doing C++ regular during the 2000's, and I only have about 5 tutorials.
Been doing too much C lately to keep up on all these new style bugs.

Last edited by selfprogrammed; 08-31-2017 at 05:15 PM.
 
Old 09-01-2017, 09:18 AM   #2
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,632
Blog Entries: 4

Rep: Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931
Don't change any source-code. The problem will be a missing include-file, or an omission in the include-path directive: perhaps a co-requisite distro package that is not installed and that is not properly recognized as a co-requisite.

Contact the publisher of SimGear for technical assistance. Do not meddle with their source-code because you know that it (should) work.
 
Old 09-02-2017, 03:05 PM   #3
selfprogrammed
Member
 
Registered: Jan 2010
Location: Minnesota, USA
Distribution: Slackware 13.37, 14.2, 15.0
Posts: 635

Original Poster
Rep: Reputation: 154Reputation: 154
I have to edit the source code so many distributed programs that I keep a directory of FIXES that I have to re-apply when I upgrade the OS and start this process all over again.
It is sickening how many programs I have to patch.
Many of them are due to having a newer compiler that has gotten more picky. But a whole lot of them are due to out-right laziness by the original code writers. In more than a few I have had to add functions and capability.

I also work on a large free program, but I have gotten that to compile now without error messages or warnings.

For example, in dosbox-0.74, they use offsetof(). I have used offsetof myself.
I finally realized that the new compiler was mis-defining offsetof, they offered a built-in offsetof and you have to add a #define to make offsetof work. It is in the g++ info pages.
I really would like to find out what that was about, but I suspect that some version of Posix that they are now more exactly adhering to does not require offsetof.

I have cut out the offending threads code (mentioned in my OP) and taken it to a little standalone program to test it out.

It will throw out that error message no matter how I try to use ReentrantMutex.
There are no other include files to use. The class Mutex and enum MUTEX_RECURSIVE are defined right there in the class Mutex in the Mutex include file.

I can make a copy of ReentrantMutex, which I call QReentrantMutex, and I have to fix that one too.
Creating a QMutex makes a difference.
Changing the usage of QMUTEX_RECURSIVE to OpenThreads::QMutex::QMUTEX_RECURSIVE actually works, but only for my class QMutex.
Doing the exact same thing to use OpenThreads::Mutex::MUTEX_RECURSIVE gives me an error message that Mutex is not defined. I can see it defined right there in the Mutex include file.

Going to the SimGear site will give me an answer that "it works for me" and for the 100's of other people that must be downloading and using that simgear. There will not be any information to be found there.

So I am asking here first, what is so messed up in this g++ on Slackware 14.2 that it behaves this way. If it actually was a bug in the simgear code, I should be able to see what it was, but I cannot fathom this one. Even in a tiny test program it fails.

There is a newer SlackBuild for the OpenSceneGraph, but that adds a fix for sound issue.
I have even been looking for unprintable characters in that include file.
As it is completely repeatable, I am not suspecting memory failure, yet.

I might help to know if anyone else has used SlackBuild on SimGear 3.4.0, or OpenSceneGraph 3.2.1, and what their results were, especially if they used g++ 5.3 or Slackware 14.2.

Because I will be distributing binaries later for my own programs, I need to know NOW if there is some issue with Slackware 14.2 installation, or the gcc 5.3 compiler, that could cause such a strange problem.

And, please stop waving your finger at me!

Last edited by selfprogrammed; 09-02-2017 at 03:08 PM.
 
Old 05-22-2018, 05:21 AM   #4
selfprogrammed
Member
 
Registered: Jan 2010
Location: Minnesota, USA
Distribution: Slackware 13.37, 14.2, 15.0
Posts: 635

Original Poster
Rep: Reputation: 154Reputation: 154
It has been a long time, but I finally have figured out what is going on.
It took 2 days of extensive testing, which I am going to bore you with because recognizing the symptoms of this problem is going to be important to the next person who gets caught by this gotcha.

In this case it could not see the enum declared within a class, within a namespace.

1) The program ought to have compiled, but has strange errors.

2) It looks like the code is right when you look at the header in /usr/include

3) Trying namespace qualifiers does not fix the problem.

4) I made a little test program, and it still failed, with the same error.
But it is so simple that it should not fail.
The observed behavior does not match the C++ ref. behaviors for visibility in a namespace.

5) I made a local copy of the the header, with the intent of making changes to it to see
what is causing the problem.
When it is substituted it for the system header, suddenly the test program compiles.
The compiler can see the enum when the include file is a local file
but not when it is in the /usr/include directory (what??, that one had me checking the online C++ references again)

6) Changing the include line in the test program
from
#include <OpenThreads/Mutex>
to
#include "/usr/include/OpenThreads/Mutex

also causes the test program to successfully compile.

7) Both clang and gcc show similar errors. The problem does not vary by which compiler is used.
So it cannot be a compiler bug, or a damaged compiler install.


SOLUTION:
The cause of this strangeness is that you have two copies of OpenThreads in your system. One is in /usr/local and the other is in /usr.
The compiler checks /usr/local first, so it is getting the header for the old version of OpenThreads.

The old version of OpenThreads does not define the enum with MUTEX_RECURSIVE, and that is why the compiler cannot find it.
You, of course, are looking in /usr/include and can see the enum defined there.

If you have a similar situation, you probably do not realize it, because you will only get compiler errors if
the old and new header versions differ in some significant way. It has to be a difference that will make a compile fail.
Most version updates do not have significant differences in headers (from the previous version), as they are fixing bugs in the implementation.

Compiling a program, using some old headers hiding in /usr/local, is very possible on Slackware.
Slackware users that install stuff before some SlackBuild is released are much more likely to run into this,
and probably do not realize it.

I now have to figure out a way to gracefully remove the old version of OpenThreads, probably by dates.


Please do not regale this thread with how you don't ever have this problem because you only install pre-built packages, etc., etc..
Yeah, we all know that if you only install packages like Debian does, or RedHat packages, or even SlackBuild packages,
that you can rely on that install method checking for previous installs using the same install method.

For those of us who work with stuff before nice install packages get developed, we need a method to
detect a previous install (such as in /usr/local/) when a nice slackware package is installed later.
Memory alone is not sufficient.
Any ideas on that ??

Interesting note:
> whereis OpenThreads
OpenThreads: /usr/include/OpenThreads

It only sees the one package.
It ought to find both and give the user a red blinking warning that it found two copies.

Last edited by selfprogrammed; 05-22-2018 at 05:48 AM.
 
Old 05-22-2018, 06:20 AM   #5
selfprogrammed
Member
 
Registered: Jan 2010
Location: Minnesota, USA
Distribution: Slackware 13.37, 14.2, 15.0
Posts: 635

Original Poster
Rep: Reputation: 154Reputation: 154
Double gotcha:

The new copy of OpenThreads came from OpenSceneGraph-3.4.0, which now includes it within OpenSceneGraph.
So it was not installed explicitly by me.

My previous OpenThreads was from before, when it was a separate.

It does not show up as a package name in either install, so there is nothing to check, except the
/usr/include files and the /usr/lib files.
 
Old 05-22-2018, 06:43 AM   #6
selfprogrammed
Member
 
Registered: Jan 2010
Location: Minnesota, USA
Distribution: Slackware 13.37, 14.2, 15.0
Posts: 635

Original Poster
Rep: Reputation: 154Reputation: 154
I could not use dates, as the new version of OpenThreads is dated 2012, and I built the old version in 2017.

I have removed
/usr/local/include/OpenThreads
/usr/local/lib/libOpenThreads*

I also found, and removed duplicates
/usr/local/bin/openal-info
/usr/local/share/openal

I recommend that anyone that has installed programs using /usr/local, to check
that a newer slackware package has not also been installed.
Check for duplicate remains in:
/usr/local/include
/usr/local/lib
/usr/local/share
/usr/local/bin

These are places where /usr/local which be searched before /usr.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
c++ enum vendtagain Programming 4 01-24-2010 02:26 AM
Questions about enum. What would be a good use of enum? RHLinuxGUY Programming 5 06-11-2006 01:13 PM
enum inheritance in C++? graemef Programming 2 01-27-2006 10:14 PM
C Enum exvor Programming 3 09-27-2005 02:51 PM
C, enum confusion cigarstub Programming 2 09-27-2005 09:59 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 06:02 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration