-
-
Notifications
You must be signed in to change notification settings - Fork 23.8k
Description
Tested versions
Godot v4.5-stable
System information
Godot v4.5.1.stable - Windows 11 (build 26100) - Multi-window, 2 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3080 Ti (NVIDIA; 32.0.15.8115) - AMD Ryzen 9 5950X 16-Core Processor (32 threads) - 95.92 GiB memory
Issue description
When passing no arguments into a variadic function, and then in that function passing these variadic parameters into another variadic function, this creates an array element instead of passing the values to "spread" as the doc calls it.
In particular, this will make code ending up calling callv completely fail for functions without arguments:
static func call_if_exists(node: Node, func_name: StringName, ...args):
print("node: %s call : %s " % [ node.name, func_name])
if node and node.has_method(func_name):
node.callv(func_name, args)
static func call_any_if_exists(nodes: Array[Node], func_name: StringName, ...args):
for node in nodes:
call_if_exists(node, func_name, args)With the code above, calling this:
call_any_if_exists(some_nodes, "some_function") # no additional argumentswill trigger an error when callv in above code snippet is called, making variadic arguments almost impossible to use generically.
In my own project, using that same code, the error looks like this:
E 0:00:06:138 utility.gd:10 @ call_if_exists(): Error calling method from 'callv': 'CharacterBody3D(player.gd)::on_post_restore_begin': Method expected 0 argument(s), but called with 1.
<C++ Error> Method/function failed. Returning: Variant()
<C++ Source> core/object/object.cpp:812 @ callv()
<Stack Trace> utility.gd:10 @ call_if_exists()
utility.gd:14 @ call_any_if_exists()
game_core.gd:473 @ end_game_load()
game_scene.gd:61 @ restore_save()
screen_loading_game.gd:85 @ _check_loading_status()
screen_loading_game.gd:58 @ _process()
Using the debugger to break at this point and checking the value of args in each function, I can see that each call will add an inner array element.
Note that the documentation suggests to call callv to simulate a spread, but that will not work if the parameters come from several function upper in the stack:
Steps to reproduce
In any GDScript, given this code:
func func_a(...args) -> void:
func_b(args)
func func_b(...args) -> void:
assert(args.is_empty())
func some_test() -> void:
func_a();Call some_test() to trigger the assertion and see the content of args in the debugger.
Obviously, the more calls you chain that way, the more inner arrays you will find, as per the above screenshot.
Minimal reproduction project (MRP)
N/A , see snippet above