Functions - no return node = not returning NULL values? Intended?

The old school programmer in me, always says inside my head: “you should always put a return node, even if it’s empty!” So naturally, this is what I usually do… just to be safe.

However, I had a function with an enum switch node, and only some switches are used, so I left the rest blank because there were so many entries. I assumed if it didn’t go through those nodes, it would just return with “empty” default null values. But it doesn’t…

What happens, is it was returning the last values in memory from the previous function call. Is this normal, or an unintended memory problem? I always assumed blueprints were “dummy-proof” with garbage collection and memory resets, but I guess theres some oddities?

Basically, my advice to avoid this is:

A> Always use a return node with values set!

B> If you use enum switches (which don’t have a “default”).. prefix it with a “sequence” node, so you can default out on the 2nd path after it “fails” to find a switch. This lets you avoid having to route paths for every single entry, or maybe possibly failing an integer conversion that is out of bounds.

The main reason I’m posting this, is to help someone else avoid this problem! I wasted 2 hours wondering why I was getting outdated data back in a function return, that literally didn’t exist anymore.

EDIT:
Changed topic name of “default” to “NULL” because it might have been confusing. I didn’t mean declared defaults, i meant the default null value of variables or references in blueprints.

2 Likes

Or put the empty return on the default pin :thinking:

Yes, I assume they did this to avoid the function never returning, which would confuse the pants off a lot of engine newbies :rofl:

1 Like

Like I said, it was an enum switch. There’s no default for enum switches.

Unlike C++, I would have assumed blueprints had 100% garbage collection, and would always default to NULL or 0 for every output value.

The scary thing is, it might not be better if they forced a value, cause it would add overhead to blueprint functions every time it had to check a function exit and make it dummy-proof (unless this is how blueprints should be.)

Hopefully this helps someone.

TLDR: If you have return values in a function, always add a return to every single possible route, or you’re going to get unexpected output values.

i always do a sequence like you just so i dont forget a branch somewhere,

but my understanding is since blueprints cant return a reference the ReturnNode is basically a LocalVariable copy. so it would be the default value of that local copy. As opposed to garbage.

Good point :blush:

I’m a fanatic about using sequences and returns in functions. Can’t think of a single instance where I was getting unexpected values though. Even with enum switches. I’m heavy handed on validation, so that might be it.

Your function doesn’t have outputs there, but as long as you keep every exit path with a return, you’re fine.

This is what I’m talking about.

In this case, the first use of the function using “down and up” will return with the texture. If you use the function again with “mouse up” you would figure it’d just return with an empty NULL texture (like mouse down does), but instead it will send the last output value that was in memory.

I’m sure theres tons of devs out there that might not realize this, since the compiler doesn’t yell at you for missing returns. I’ve even seen plenty of videos where people don’t fill them all out.

Anyway… I guess the moral is: anyone out there who is assuming they are NULL values, should go fix their code! :slight_smile:

EDIT:

An extra warning - make sure you don’t go crazy plastering returns everywhere without thinking. I sometimes catch myself almost putting them inside of a loop because I see a dead end path, and then realize it’s not supposed to end!

I have functions that use returns and force exits with null values. They are checked on exit prior to next logic step down the chain.


My custom Enumerators also have a None/Default/Fail/Fault to use as a logic validator.

I also don’t have any exits/ends not process a return node. If one has a return then all have a return.

Move Up and Precise Click should have a Return Node even if the value is NULL.


Yes, like I said in the first post. The point of this post, is that it’s a warning to anyone who doesn’t fill out every exit path (like in the screenshot example.) But thank you for the input.