hxcpp icon indicating copy to clipboard operation
hxcpp copied to clipboard

Functions which take Void as an argument cause the C++ compiler to error

Open graysus opened this issue 6 months ago • 3 comments

package;

class Main {
	public static function main():Void {
		var x:(Void)->Void = _ -> {
			// bad function
		}
	}
}

Compiling this code gives an error from the C++ compiler:

$ haxe --cpp out Main.hx
haxelib run hxcpp Build.xml haxe -Dhaxe="4.3.7" -Dhaxe3="1" -Dhaxe4="1" -Dhaxe_ver="4.307" -Dhxcpp_api_level="430" -Dhxcpp_smart_strings="1" -Dsource_header="Generated by Haxe 4.3.7" -Dstatic="1" -Dtarget.atomics="1" -Dtarget.name="cpp" -Dtarget.static="1" -Dtarget.sys="1" -Dtarget.threaded="1" -Dtarget.unicode="1" -Dtarget.utf16="1" -Dutf16="1" -I -I/usr/share/haxe/std/cpp/_std/ -I/usr/share/haxe/std/
Creating /home/user/bug_report_hxcpp/out/obj/linux64/__pch/haxe/hxcpp.h.gch...

Compiling group: haxe
g++ -Iinclude -c -fvisibility=hidden -O2 -fpic -fPIC -Wno-overflow -DHX_LINUX -DHXCPP_M64 -DHXCPP_VISIT_ALLOCS(haxe) -DHX_SMART_STRINGS(haxe) -DHXCPP_API_LEVEL=430(haxe) -m64 -DHXCPP_M64 -I/home/user/haxe/hxcpp/4,3,2/include ... tags=[haxe,static]
 - src/Main.cpp 
Error: ./src/Main.cpp: In static member function ‘static void Main_obj::main()’:
./src/Main.cpp:29:43: error: invalid use of type ‘void’ in parameter declaration
   29 |                         void _hx_run(void _){
      |                                      ~~~~~^

On other targets, this compiles without emitting an error. I am using Linux, Haxe version 4.3.7, hxcpp version 4.3.2, and g++ version 15.1.1

graysus avatar Jun 16 '25 03:06 graysus

The syntax Void->Void doesn't mean that the function takes Void as an argument (Void cannot be used as a value in haxe) but rather that it accepts no arguments. So assigning it to a function which does have one argument _ -> {} causes the problem, what you want to do is assign a function which accepts no arguments () -> {}.

This only "works" due to a very cursed haxe "feature" involving dynamic and function arguments, In your case _ defaults to dynamic since it's not explicitly typed or infered from use.

https://github.com/HaxeFoundation/haxe/wiki/Haxe-function-typing-incompatibilities-with-static-targets

Strictly speaking hxcpp should support this to match other targets but there's no reason to be writing code like this so I have no intention in changing it.

Aidan63 avatar Jun 17 '25 09:06 Aidan63

I wrote (Void)->Void, which is interpreted as a function taking a Void argument. Changing it to Void->Void fails to compile (as expected):

Main.hx:5: lines 5-7 : (_ : Unknown<0>) -> Void should be () -> Void

The code I wrote was somewhat of a bad example, but it could be confusing if you're using inferred types, for example:

static function foo<T>(func:(Int, T)->T) {
	// ...
}
public static function main():Void {
	foo((x, y) -> 5);
	
	// y is inferred here to be Void, because the return is also Void.
	foo((x, y) -> {
		trace("Hello, World!");
	});
}

This gives the same error as the other example, and no information as to which line is causing the problem.

graysus avatar Jun 18 '25 22:06 graysus

I wonder if https://github.com/HaxeFoundation/haxe/pull/11558 might turn the (Void)->Void case into a haxe-side compiler error.

tobil4sk avatar Nov 06 '25 12:11 tobil4sk