DLL functions that return void

BlitzMax Forums/BlitzMax Programming/DLL functions that return void

JoshK(Posted 2014) [#1]
If I have a function in a C++ DLL like this:
void DoSomething()

Am I safe if it's declared in BMX like this?:
SuperStrict

Extern "C"
Function DoSomething()
EndExtern

Or is there an implied Integer returned?


JoshK(Posted 2014) [#2]
This code fails to compile:
SuperStrict

Local n:Int=test()
Print n

Function test()
	Return 3
EndFunction

But this code will print '0':
SuperStrict

Local n:Int=test()
Print n

Function test()
	'Return 3
EndFunction

I assume externed functions that don't return anything are safe?


feeble1(Posted 2014) [#3]
Function test:int()

You need to tell max what you are returning if you are using super strict.


Derron(Posted 2014) [#4]
without ":int" you always are allowed to just "return" (without a value).

@void
void means what it says: nothing is returned
So it does not need (nor is it "allowed") an ":int" or so ...


bye
Ron


Brucey(Posted 2014) [#5]
Am I safe if it's declared in BMX like this? ... Or is there an implied Integer returned?

As far as I can tell with the way the generated code works, there is indeed an implied Integer return, despite using SuperStrict and not defining a return type. It may be that the generated asm handles this somehow - or your app may crash (perhaps not now, but sometime later - read undefined behaviour)

However with NG, because everything becomes C, and interacts directly with C/C++, when you use SuperStrict and do not define a return type, your extern function will not return anything - in fact, the compile should fail as it would with a normal function.


Yasha(Posted 2014) [#6]
On x86 and amd64 there's no difference between the two anyway. So as long as you're using stock BlitzMax, this isn't going to be a problem, crash-wise.

Returned small values - ints and pointers - go in registers, so there's no stack manipulation. The only difference between int and void as a return type is whether the function bothered to modify the value of EAX, and whether the surrounding code is supposed to inspect it immediately afterwards. The only significant risk therefore is if you declare a void function as pointer-returning and accidentally expose a pointer to garbage data; accidentally exposing an invalid int is annoying, but not a real problem since it doesn't lead to any extra memory. Since the default type is int, which is safe, you should also be safe.


Brucey(Posted 2014) [#7]
The value returned may also be "undefined" if the external function isn't actually returning anything.

I've had experience in BlitzMax where I expecting a value from a C function but not defining/returning a value - the value going into the BlitzMax variable was not always zero (hence, undefined). This was on OS X, which tends to prefer to pass undefined values around if you don't set up the program properly.


Henri(Posted 2014) [#8]
If there is a function in C that returns void I have never declared any return value in BMAX.

-Henri


JoshK(Posted 2014) [#9]
Should the correct way of handling this to always make externed functions return an integer, even if it's not needed? I can do that but don't want to do it for no reason.


Brucey(Posted 2014) [#10]
The correct way is to declare the correct return type for the extern function - whether it is nothing, int, byte ptr, etc.


Derron(Posted 2014) [#11]
Return values describe what a function returns ... so if you see ":int" you will know it returns a number (or blitzmax-wise often a "boolean"). So "Setters" often only have :ints to return whether a set was successful or not.

Just adding ":int" to all functions is what I do here too (as it allows proper override - which then utilizes true/false-returns) but it is not the "common" type of defining function/method headers.

But I understand JoshKs question this way: He want to avoid "problems", and therefore asked if it would be better to replace "voids" with "int" just to "make safe".


bye
Ron


Henri(Posted 2014) [#12]
In the official help file void is handled with no return type, which is what should be. If I understand correctly BlitzMax (or C) internally defaults to int , but if void is specified in C-function then returning value can be anything and is bad practise to specify int in Blitz definition (and assume that something meaningfull is returned).

-Henri


Yasha(Posted 2014) [#13]
In case post #6 was confusing, let me try to rephrase that:

Using the correct type, or lack thereof, is safe, even in the presence of compiler bugs like the one demonstrated in post #2, for two reasons:

- Max doesn't manipulate the stack for any return types, so a mistype can't cause stack corruption
- Max defaults to a return type that can't cause memory leaks/dangling pointers/whatever

You should still use the right type; the point is that the bug in post #2 won't cause a crash anywhere, because there's no difference in the calling machine code. So it's non-critical, and you shouldn't "work around" it yourself by adding types that don't exist.

(misdeclaring the number of arguments will make a difference if it's a stdcall/"Win32" function, but that's a separate issue)


JoshK(Posted 2014) [#14]
Okay just making sure. Thanks.