NEURON uses reserved identifiers & doesn't define its API #2234
Labels
api
bug
dev
Developer Tickets
improvement
Improvement over existing implementation
nmodl
proposal
refactoring
wheel
Context
This issue mixes two somewhat different issues, on the basis that it makes sense to solve / consider them at the same time:
nocmodl
, uses identifiers that are reserved for the C++ implementation (they start with underscores in the global namespace, see https://en.cppreference.com/w/cpp/language/identifiers). This is bad practice and may lead to surprising problems in the future.Overview of the issue
Currently the main issue linked to #1963 relates to the pre- and post-C++11 ABI for
std::string
. In themanylinux2014
image used to build Python wheels, the old C++11-noncompliant version ofstd::string
is used. Whennrnivmodl
is run on a user machine using any reasonable toolchain, the C++11 compliant version is used. See this page for more information.This issue with
std::string
will likely (to be checked!) go away when we eventually move to usingmanylinux_2_28
-based images to build the Python wheels. One thing to explore at that stage will be whether it causes issues to runnrnivmodl
on a user machine with a toolchain based on an older GCC than was used to compile NEURON.manylinux_2_28
images currently use GCC 12.One thing we can do to reduce exposure to issues such as this one would be to define and restrict the interface between code generated from MOD files (which is built inside
nrnivmodl
) and code that forms part of the main NEURON library (which is built earlier, potentially on a different machine using a different toolchain). At the moment this interface is only implicitly defined, and there is no explicit restriction on what data types may be passed back and forth across the interface between generated code and the NEURON library.If this interface was explicitly defined, it might be possible to use tools like abi-compliance-checker to check consistency between what we obtain in a "standard" build and what we obtain when using the Python wheels.
As part of explicitly defining this interface, we could also reorganise the naming conventions to avoid reserved identifiers.
The use of leading underscores is widespread because NMODL variables defined in MOD files cannot start with underscores, so this avoids clashes with the preprocessor macros that
nocmodl
generates to represent NMODL variables.Expected result/behavior
Everything should work and we should never have to debug weird Python-wheel-specific bugs ever again.
Suggested solution
A tentative suggestion for how to address the above is as follows:
nocmodl
should stop emitting its own declarations for methods hidden inside the NEURON library.neuron::mechanism::(anonymous namespace)::foo
neuron::mechanism::
namespace_
_register::_thread_table(...)
instead of_nrn_thread_table_reg(...)
in translated code, which would callneuron::mechanism::_register::_table_thread(...)
(because the generated call is inside theneuron::mechanism
namespace)neuron::mechanism::
namespace should be required to use "simple" data types. For example,std::string
and types containingstd::string
member variables are banned. For example, we might only allow the use of plain C/C++ data types andT*
whereT
is a forward-declared type.(for extra "fun": define variables called
int
,double
, ...)nmodl_variable_columnindex
macros; theends_with_underscore_
example above results inends_with_underscore__columnindex
, which contains a double underscore. That is a reserved identifier, but I am not 100% sure if it is a permissible macro name -- probably not)The text was updated successfully, but these errors were encountered: