Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix OpenSim's property macros are namespace-dependent #3468

Closed
adamkewley opened this issue May 26, 2023 · 0 comments
Closed

Fix OpenSim's property macros are namespace-dependent #3468

adamkewley opened this issue May 26, 2023 · 0 comments
Assignees

Comments

@adamkewley
Copy link
Contributor

If I write a custom component class that lies outside of the OpenSim namespace:

namespace
{
  class FrameDefinitionMesh final : public OpenSim::Component {
      OpenSim_DECLARE_CONCRETE_OBJECT(FrameDefinitionMesh, OpenSim::Component);
  public:
      OpenSim_DECLARE_PROPERTY(scale_factors, SimTK::Vec3, "scale factors in X, Y, and Z directions of the mesh");
  };
}

Then it will fail to compile unless the anonymous namespace is named OpenSim, or a using namespace OpenSim; declaration is placed above the class declaration. Example compiler errors:

FrameDefinitionTab.cpp(58): error C3646: 'PropertyIndex_scale_factors': unknown override specifier
FrameDefinitionTab.cpp(58): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
FrameDefinitionTab.cpp(58): error C2143: syntax error: missing ';' before '<'
FrameDefinitionTab.cpp(58): error C2334: unexpected token(s) preceding '{'; skipping apparent function body
FrameDefinitionTab.cpp(58): error C2327: '`anonymous-namespace'::FrameDefinitionMesh::Property': is not a type name, static, or enumerator
FrameDefinitionTab.cpp(56): error C2280: '`anonymous-namespace'::FrameDefinitionMesh &`anonymous-namespace'::FrameDefinitionMesh::operator =(const `anonymous-namespace'::FrameDefinitionMesh &)': attempting to reference a deleted function
  FrameDefinitionTab.cpp(59): note: compiler has generated '`anonymous-namespace'::FrameDefinitionMesh::operator =' here
  FrameDefinitionTab.cpp(59): note: '`anonymous-namespace'::FrameDefinitionMesh &`anonymous-namespace'::FrameDefinitionMesh::operator =(const `anonymous-namespace'::FrameDefinitionMesh &)': function was implicitly deleted because '`anonymous-namespace'::FrameDefinitionMesh' has a data member '`anonymous-namespace'::FrameDefinitionMesh::Property' of const-qualified non-class type
  FrameDefinitionTab.cpp(58): note: see declaration of '`anonymous-namespace'::FrameDefinitionMesh::Property'
FrameDefinitionTab.cpp(58): error C2065: 'PropertyIndex_scale_factors': undeclared identifier
FrameDefinitionTab.cpp(58): error C2039: 'PropertyIndex_scale_factors': is not a member of '`anonymous-namespace'::FrameDefinitionMesh'
  FrameDefinitionTab.cpp(55): note: see declaration of '`anonymous-namespace'::FrameDefinitionMesh'
FrameDefinitionTab.cpp(58): error C2039: 'updProperty_scale_factors': is not a member of '`anonymous-namespace'::FrameDefinitionMesh'
  FrameDefinitionTab.cpp(55): note: see declaration of '`anonymous-namespace'::FrameDefinitionMesh'
FrameDefinitionTab.cpp(58): error C2039: 'getProperty_scale_factors': is not a member of '`anonymous-namespace'::FrameDefinitionMesh'
  FrameDefinitionTab.cpp(55): note: see declaration of '`anonymous-namespace'::FrameDefinitionMesh'

The reason this happens is because the macros are written with the assumption that they will be expanded inside those namespaces (or, with those namespaces brought into the global namespace via a using namespace declaration).

E.g. the OpenSim_DECLARE_PROPERTY_HELPER_PROPERTY_MEMBERS macro in Property.h uses an OpenSim::PropertyIndex without the namespace qualifier, so the compiler will fail to find PropertyIndex unless the expansion point is defined within OpenSim or is inside a block that has a using namespace declaration:

// OpenSim/Common/Property.h:1255

// Used by OpenSim_DECLARE_PROPERTY_HELPER below to control the members
// that are used with SWIG.
#ifndef SWIG
#define OpenSim_DECLARE_PROPERTY_HELPER_PROPERTY_MEMBERS(name, T)           \
    /** @cond **/                                                           \
    PropertyIndex PropertyIndex_##name;                                     \
    const Property<T>& getProperty_##name() const                           \
    {   return this->template getProperty<T>(PropertyIndex_##name); }       \
    Property<T>& updProperty_##name()                                       \
    {   return this->template updProperty<T>(PropertyIndex_##name); }       \
    /** @endcond **/
#else
// No need to wrap internal PropertyIndex or auto-generated methods that return
// templatized Properties
#define OpenSim_DECLARE_PROPERTY_HELPER_PROPERTY_MEMBERS(name, T)
#endif

OpenSim Creator entirely bans using namespace, purely as a defensive measure, but this means that I either have to drop the rule when using OpenSim (undesirable), or define all of my downstream components within the OpenSim namespace (also undesirable).

@adamkewley adamkewley self-assigned this May 26, 2023
adamkewley added a commit that referenced this issue May 30, 2023
…ace-independent

Make OpenSim macros namespace-independent (#3468)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant