• 9
• 9
• 10
• 10
• 9

# Why asEP_ALLOW_UNSAFE_REFERENCES is "UnSafe" ?

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

## Recommended Posts

I'm still not understand why asEP_ALLOW_UNSAFE_REFERENCES is unsafe?

Consider these two angelscript functions:

void FuncA(uint64& lhs, const uint64& rhs)
{
lhs += rhs;
}

void FuncB(string& lhs, const string& rhs)
{
lhs += rhs;
}


"FuncA" receive primary type arguments by reference, and "FuncB" using value type arguments. No need to adjust the reference count in this case. Because the caller of FuncA and FuncB can not make lhs and rhs invalid before the function return. i.e.: lhs and rhs must be valid during the function call.

Let's consider some asynchronous cases:

void FuncC(uint64& lhs, const uint64& rhs)
{
lhs += rhs;
globle_int_for_later_use = lhs;
}

void FuncD(string& lhs, const string& rhs)
{
lhs += rhs;
globle_str_for_later_use = lhs;
}


In "FuncC" and "FuncD",  we added some deferred usage for the "lhs" argument. But it still not a problem because lhs has been copied by value for deferred use. So it still keeping safe even if the caller destroy the lhs variable immediately at the function return.

I think the only risk of "argument passing by reference" is the callee saved the address of the argument, and determine to use it later. In this case, the argument need to support reference counting to maintain its ownership and life time correctly. But as far as I known, angelscript don't support save the address of a variable to another variable, angelscript only support "copy by value" or "copy by reference counting handle", right?

Of course the calee could even destroy the argument forcefully in c++ through something like: "delete &lhs / free(&lhs)" and make things unsafe. But again, it is not allowed in AngelScript.

So what is the risk of this option?

Edited by ASBai

##### Share on other sites

Let me explain with an example:

array<string> arr = {'hello'};
void foo(string &val)
{
arr.resize(0);
val = 'hello world';
}


With asEP_ALLOW_UNSAFE_REFERENCES turned on this code is legal. However, what happens if the function 'foo' is called passing in a reference to an element of the global array 'arr'? The result is undefined, and very likely to crash the application.

With asEP_ALLOW_UNSAFE_REFERENCES turned off, the compiler will not allow this code, thus preventing the accidental crash of the application due to badly written scripts.

If you trust your script writers to write proper code and perform the necessary tests, then unsafe references are no more unsafe than references are in C++. But if your scripts are open to the end users, i.e. you have no control of the content, then you may not want to risk having someone write a bad script that crash the application (or worse, exploit some memory invasion due to unsafe references to hack your computer).

Got it, thanks

:)

##### Share on other sites

For the same reason, AngelScript does not provide iterator support for container types like array, dictionary?

##### Share on other sites

Not, really. Iterators can be made safe, especially when the container already support handles (i.e. has a reference counter).

The lack of iterators is more due to not having found the time nor the desire to implement fully working iterators. I concentrate most of my effort on the core library and not on the add-ons. The add-ons are mostly provided to give a base for developers to work upon, and are not meant to be feature complete.

If you're looking for more feature complete containers I recommend you take a look at Sami's AngelScript Add-on Template Library

Regards,

Andreas

##### Share on other sites

Thanks, it seems just what I'm looking for :-)

##### Share on other sites

When we enable asEP_ALLOW_UNSAFE_REFERENCES option, we sacrifice a little safety for get some performance boost.

Can you also provide another option what don't call AddRef and Release even for a reference type?

Because:

1.By enable asEP_ALLOW_UNSAFE_REFERENCES, we already added a hole on the engine. Colleagues (They can be trusted) already known they could not do things like your example. So, why not further boost some performance under this situation?

2.One big advantage of AngelScript is it almost compatible with C++. So for some modules, we can write them in early stage using script for easy writing and fast prototype, and porting them to Native C++ for performance optimization. In this case, we hope that the script can be compatible with C++ as much as possible. Therefore, illegal usages in C++ should also be illegal in the script. This can greatly reduce the cost of code migration.

Edited by ASBai

##### Share on other sites

You can register the object types with the flag asOBJ_NOCOUNT. In this case AngelScript assumes the application will take care of the memory management through some other way and won't require the addref and release behaviours.

##### Share on other sites

No, asOBJ_NOCOUNT doesn't meet the requirement, for example:

CMyRefType obj;

// ...
void Func(const CMyRefType& arg) // No AddRef here
{
global_handle_for_later_use = @arg; // NEED AddRef here

} // No Release here


?

This semantics is equivalent to the corresponding C++ code:

typedef shared_ptr< obj > MYREFTYPEHDL;
MYREFTYPEHDL global_handle_for_later_use;

// ...
CMyRefType obj;

// ...
void Func(const MYREFTYPEHDL& arg) // No AddRef here
{
global_handle_for_later_use = arg; // NEED AddRef here

} // No Release here

Edited by ASBai

##### Share on other sites

I think the most efficient way to implement this function is add a compiling time macro like:

#define ALLOW_ALL_UNSAFE_REFERENCES

With this macro defined, all arguments passed by reference are simply an address delivery. This can eliminate all runtime checking and other related works for the engine?

Edited by ASBai