Delegate Scope confusion with C++ function

I’m confused of the correct scope of delegate in C++. Here is an example:

I made an delegate declearation : DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnStart)

And I let the object A hold the delegate: A { ... FOnStart OnStart ... };

And instead of call member function directly, I bind member function of A to the delegate, and brocast the delegate.

void UObjectA::Start()
{
	this->OnStart.AddDynamic(this, &UObjectA::Then);
	this->OnStart.Broadcast();
}

So when the function Then() is started, is function Start() already finished? Or the program is still in scope of function Start()? I read the documentation of delegates, and I assume it is some kind of function pointer. But I still need to confirm this assumption.

You are correct that the idea of adding bound functions to a list to be called later is not an accurate description of how broadcasting works in Unreal Engine or other similar systems.

In Unreal Engine, broadcasting is a synchronous operation where the bound functions are executed immediately in the order they were added to the delegate. As your test demonstrates, the bound function is executed before the log message after the broadcast call, which confirms that the execution of the function is not deferred to a later time.

It’s possible that the confusion may arise from the fact that delegates in Unreal Engine can support both synchronous and asynchronous invocation, depending on the type of delegate used. For example, a multicast delegate supports synchronous invocation, while a dynamic delegate supports asynchronous invocation.

Therefore, it’s important to distinguish between the different types of delegates and their invocation behavior when discussing broadcasting in Unreal Engine.

Where does that idea come from? Feel free to prove me wrong, but as far as I’m aware this has never been the case. It’s not the first time I hear about it though.

I just did a simple test to make sure I’m not crazy (UE5.1) :

void UObjectA::Start()
{
    OnStart.AddUniqueDynamic(this, &UObjectA::Then);
    UE_LOG(LogTemp, Log, TEXT("***** Pre-Broadcast *****"));
    OnStart.Broadcast();
    UE_LOG(LogTemp, Log, TEXT("***** Post-Broadcast *****"));
}
void UObjectA::Then()
{
    UE_LOG(LogTemp, Log, TEXT("***** Then() *****");
}

I get the following result :

[2023.03.10-14.17.46:481][439]LogTemp: ***** Pre-Broadcast *****
[2023.03.10-14.17.46:481][439]LogTemp: ***** Then() *****
[2023.03.10-14.17.46:481][439]LogTemp: ***** Post-Broadcast *****

Same thing with a blueprint dispatcher :

[2023.03.10-14.17.46:281][419]LogBlueprintUserMessages: [TestDispatcher_C_1] Client 1: PRE CALL
[2023.03.10-14.17.46:281][419]LogBlueprintUserMessages: [TestDispatcher_C_1] Client 1: EXEC BOUND FUNCTION
[2023.03.10-14.17.46:281][419]LogBlueprintUserMessages: [TestDispatcher_C_1] Client 1: POST CALL