1.While playing with structures i´ve noticed that the compiler throws an misleading error when you pass
a different structure than the callee expects: "error XS1620: Argument 1 must be passed with the 'ref' keyword"
Such an misleading XS1620 error happens when you do something like this:
IF GetVersionEx ( struInfoExW ) // wrong structure - OSVERSIONINFOEXW
IF GetVersionEx ( struInfoEx ) // correct structure - OSVERSIONINFOEX
2. I´m able to compile a "_DLL" import not only as "ANSI" or "UNICODE", but with "AUTO" too, though "AUTO" seems to have no effect at runtime. For what is "AUTO" good for in this context ?
There are some more notes in the attached app, so i thing it should be easy to follow what i´m doing and how i´m using the import possibilities
"_DLL" / "[DllImport" and the charsets Ansi,UniCode and Auto.
BTW I. the StructureTest.viaef has no references to any Vulcan dll or X# dll. Also, the warning 0170 is disabeld via "/nowarn:170" . The structure member "szCSDVersion" is only filled when you´re running Win7 SP1 or Vista SPx. Win 8.1 and Win 10 have no servicepacks.
BTW II. very nice to be able to do something like this now:
? "OutPut: " + lStart + " " + dwStart
// Of course, lStart is a LOGIC and dwStart a DWORD
1. About the misleading error, the problem is that the function requires a param by REF:
_DLL FUNCTION GetVersionEx ( struOS REF OSVERSIONINFOEX ) AS LOGIC
But the code calls it (as in VO), without indicating that the param is actually passed by reference:
GetVersionEx ( struInfoEx )
In Roslyn/c# this would throw a compiler error, but it is allowed in X# for compatibility with VO/Vulcan, although the "more correct" or advised syntax to use would be to explicitly specify that you pass the param by reference:
GetVersionEx ( REF struInfoEx )
Now if you had used the wrong structure (struInfoExW) in your case, you would get a proper error message:
error XS1503: Argument 1: cannot convert from 'ref OSVERSIONINFOEXW' to 'ref OSVERSIONINFOEX'
The reason why you do not get a better error message in the original sample, is due to the X# compiler trickery that takes place and tries to decide if you actually intended to pass a param by reference but did not explicitly mentioned that in the code, in which case the compiler silently and adds the "REF" itself. Apparently something goes wrong in that routine in this particular case and confuses the compiler, making it report an error about not using REF yourself, while actually the real problem is that you used the wrong structure. Not sure how easy it will be to fix this, but I will enter it a a bug report.
2. For things like that, it is extremely helpful to check the generated code/function declarations with ILSpy, to see what the compiler did differently in each case. If you do that, you will see that when using ANSI, the compiler generates this attribute for the function/method:
it explains what Auto stands for in different OSes.
If you want to have full control over things, it's maybe a good idea to not rely on _DLL declarations, but instead always apply the DllImport attribute yourself to class methods, so you always know what gets emitted.
3. Actually I do not like this and would had liked to be disallowed in X# . It is supported by c#/Roslyn so also supported by X# which uses Roslyn as its backend, but in my opinion it is error prone, as it could hide coding errors where the user typed the wrong variable. In my opinion, it would be better to use this also easy syntax instead:
i see the point. Adding "REF" shows the real problem. In a forum sample that uses ref vars i saw that there
the "REF" Keyword is not used, so i did it the same way - without thinking about why . Wouldn´t it be better - and more readable - that the compiler would force us to insert "REF" instead of adding it silently to the IL Code if it´s missing. ?
The code below runs, but if you don´t know the callee signature a quick look at the caller only suggests that in the first case only the first param is a ref var, and in the second case only the second param.
Foo ( REF dw1 , dw2 )
Foo ( dw1 , REF dw2 )
FUNCTION Foo( dwOne REF DWORD , dwTwo REF DWORD ) AS LOGIC
> ? "OutPut: " + lStart + " " + dwStart
I discovered it by accident, and i´ll use this "feature" only where i quickly need an output without to worry about the Datatypes.
Yes, this is also a preference of mine, I was actually strongly suggesting it in the vulcan years, too, because using REF explicitly makes the code a lot more readable/understandable of what it's doing.
Possibly we will make that code requiring REF in X# at some point, but as Wolfgang said we need to support also the "old" way, because there's so much existing code without it, so the new behavior must be optional. Maybe with a /strict compiler option or something like that.
That could be a possibility, but it is not easy. First of all, it would have to be an optional feature, because some people do not like this change , also we try to keep the changes to as few as possible, because some people need to share code between VO/X# while porting step by step to X#.
The big issue is that in order to implement that, the XPorter needs to become much smarter, it needs to analyze LOCALs and params, to find their types, then lookup the method signatures of that type and figure out if each param should be passed by REF or not. It's doable, but needs a lot of work, so I am afraid this one of those "nice to have" things which have to wait for after we're finished with more pressuring things like the runtime.
it´s not a showstopper, but i´m able to write "code" like below. Only when i add to such a textline a space char followed by some more text an "XS9002: Parser: unexpected input" error is thrown. It seems, that this only happens if a dialect other than <core> is selected. Only <core> throws immediately an error.
BTW. Is it possible to add the *.viaef extension to the list of allowed upload files ?
Oops . Very strange that there's no error in that code for non-Core,.will log this as a bug of course, thanks. I will also add .viaef in the list of allowable files, well as soon as I discover where that setting is