2.23.1: Unable to access functions in global scope from within namespace (plus a bit on the scope resolution operator with namespaces)

This topic is 2158 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Pretty clear with code:
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void GlobalFunction() { Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called."); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ namespace MyNamespace { void NamespacedFunction() { Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called."); GlobalFunction(); // No matching signatures to 'GlobalFunction()' ::GlobalFunction(); // No matching signatures to '::GlobalFunction()' } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { GlobalFunction(); MyNamespace::NamespacedFunction(); } 

I first noted this problem when attempting to use sqrt (from the scriptmath addon) from within a namespaced function. I worked around it by registering scriptmath inside a "Math" namespace, but that's hardly ideal. To me all functions in a parent namespace, unless masked by another function in a closer relation, such as the same namespace, should be accessible in all children namespaces. If a function is masked, it should be accessible with the right use of scope resolution.

Which leads me to: the global scope operator doesn't play with namespaces. This could make situations like the below rather interesting...
 void MyFunction() { Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called."); } namespace MyNamespace { void MyFunction() { Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called."); } void NamespacedFunction() { MyFunction(); // Which function is this referencing? I assume it's the one in the current namespace! ::MyFunction(); // Which implies that this should be the syntax to access the one in the global namespace... } } 

I understand the global scope operator is currently designed to access global variables, as in:
 // From http://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html int value; void function() { int value; // local variable overloads the global variable ::value = value; // use scope resolution operator to refer to the global variable } 
However, as it is also the namespace resolution operator I was expecting it to work for accessing the global namespace as well...

Share on other sites
Just saw "Accessing entitites in global scope from a function in a namespace didn't work (Thanks _Vicious_)" d'oh...

Share on other sites

Did the fix provided for problem reported by _Vicious_ solve your issue too?

Observe that the namespace feature is still quite new in AngelScript, and doesn't have quite all capabilities that is available in for example C++. For one thing, AngelScript currently does not recursively search parent namespaces for matching symbol names. Only the current namespace is search, or if another explicit namespace is given, then that one is used instead.

I intend to implement the recursive search of parent namespaces, but I'm not sure when I'll get to it.

Share on other sites
I'm not sure about _Vicious_'s fix, but I expect so. It sounds the same.

I know it's fresh. The inclusion of namespaces is why I upgraded AS in our engine - it was of more worth to me than most of the bug fixes.

Understandable about the searching - so long as that is documented. http://www.angelcode.com/angelscript/sdk/docs/manual/doc_global.html#doc_global_namespace doesn't currently mention this situation, leading to the expectation of C++-esque functionality. I'd recommend, and I know I'm not in a place to say anything about your project's direction, that in the current situation blocking access to the objects in the global scope (2.23.1's current functionality) by default, but then allowing access through the explicit use of the global scope resolution operation "::MyFunction()" would make the system self-consistent. The global scope operator is documented here for our convenience: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html#scope

Thank you very much for an amazing tool.

Share on other sites
The documentation can definitely be improved. I'll add this for the next release.

Everyone gets a say in the project's direction. AngelScript has far exceeded my own needs for a scripting library many years ago. Nowadays I'm working on this library more for the community than for my own use. I listen to the users feedback and decide what seems to benefit the most of you. When opinions diverge but there is a possibility to make an option configurable without negatively impacting everyone I'll try that as well.

For example, whether or not to do a recursive search in parent namespaces might be something I'll make configurable with an engine property.

Share on other sites
Hello.

I've just tried this with version 2.23.1 of angelscript and it doesn't work for function calls
Even if I add "::function", it won't resolve to Global scope.

As for the way of resolving scope, I would like to say that I'm OK with either of the alternatives (automatic recursive resolution or manually specifying "::"), as long as the documentation states it clearly ;)

Thanks for the great lib, by the way

Share on other sites
By the way, I guess a simple, yet not very nice, way to solve this problem is adding everything to another namespace called "global" and always make reference to it.

In the application:
 engine->SetDefaultNamespace ("Global"); engine->RegisterGlobalFunction("void print (string &in)", asFUNCTION(print), asCALL_CDECL);

In the script:
 void MyFunction () { Global::print ("OMG!! it works!!111"); }

Of course, this doesn't look nice at all. But it's a temporary solution Edited by alraz

Share on other sites
Try it again with version 2.24.0 please, and let me know if still doesn't work.

Share on other sites

Try it again with version 2.24.0 please, and let me know if still doesn't work.

Tested... and it works! \o/

Thank you so much

script used for testing, compiles and runs smoothly:

 float calc(float a, float b) { // Print the value that we received print("Received: " + a + ", " + b + "\n"); // Print the current system time //print("System has been running for " + pow (2,16) + " seconds\n"); // Do the calculation and return the value to the application return a * b; } namespace A { dictionary Dic; void main () { float Out; Dic.set ("Value", ::calc (1.1,2.0)); Dic.get ("Value", Out); ::print ("Value: " + Out + "\n"); } } 

Of course, it has Dictionary, String, Array and Math functions registered. Edited by alraz

Share on other sites
Thanks for the confirmation

• 22
• 10
• 19
• 15
• 14