rusty icon indicating copy to clipboard operation
rusty copied to clipboard

cannot mix implicit and explicit call parameters

Open rarris opened this issue 3 years ago • 5 comments

PROGRAM mainProg
VAR
str : STRING;
TMPstr : STRING := 'abc';
END_VAR
logg(Str := CONCAT(TMPstr, 'wwww'), global3);
END_PROGRAM
FUNCTION logg : BOOL
VAR_INPUT
	Str : STRING[255];
	debug : DWORD;
END_VAR
VAR
END_VAR
END_FUNCTION
VAR_GLOBAL
global3 : DWORD;
END_VAR

error: Cannot mix implicit and explicit call parameters! ┌─ test.st:60:38 │ 60 │ logg(Str := CONCAT(TMPstr, 'wwww'), global3); │ ^^^^^^^ Cannot mix implicit and explicit call parameters!

rarris avatar Nov 30 '22 08:11 rarris

what are the circumstances where this is allowed? @ghaith do you know the rules here? assume

FUNCTION foo: VOID
   VAR_INPUT a, b, c : INT; END_VAR
   ...
END_FUNCTION
  • do you need to provider the parameters in order?
    • foo(a:=1, 2, c:=3); b=2
  • can I pass the explicit assignments out of order?
    • foo(c:=3, 2, a:=1); b=2
  • can I maybe only provide one last parameter implicitly, or can I pass as many as I like, what if they are out of order?
    • foo(c:=3, 4, 5); a=4? b=5?

riederm avatar Dec 01 '22 12:12 riederm

I had a look in the standard about this (6.6.1.4 Call representation and rules), and as far as I can tell we do not need to support this. The standard describes how formal and informal function calls need to be handled, but makes no mention of mixing the two. Consider the following paragraph about Non-formal calls:

The parameter list shall contain exactly the same number of parameters, in exactly the same order and of the same data types as given in the function definition, ...

The way I see it, as soon as one parameter is passed informally, the order and number of parameters needs to match the signature, therefore making explicit assignments to other parameters in the same call redundant.

mhasel avatar Dec 15 '22 10:12 mhasel

They are redundant, but not "Not allowed" so if a pre-existing project already has such call signatures, we could for example still support it with a warning. I would say the order will then matter.

ghaith avatar Dec 15 '22 11:12 ghaith

I might try to do this. Just making notes here so if I will not do this maybe some othe will benefit.

So these should be valid. At least we use this functionality as sometimes example first parameter is string id and you always notice that even without explicit call parameter. Second and third can be both some small integers so you need to add explicit parameter there so future you does not have to look what those meant.

foo(1, 2, 3); foo(a:=1, 2, 3); foo(a:=1, b:=2, c:=3); foo(a:=1, 2, c:=3);

Error cases. I would say let's make all of these error even though some could be just warnings. If someone has good arguments of course I would love to here.

foo(2, c:=3); MAX(IN:=1, 2)

// One problem with these is what order we validate blocks foo(a:=1, c:=3, 2); foo(a:=1, c:=3, b:=2); // Example which one we do first MAX() or MIN(). Too much // trouble for nothing. foo(a:=1, c:=MAX(2,3), b:=MIN(1,2));

foo(a:=1, 2);

teksturi avatar Nov 24 '23 02:11 teksturi

So the way I've been thinking of this is to add lints which could be configured. This is in progress in #826 . The order will always be an issue so we could assume the unnamed parameter is in its correct location and go into UB otherwise. This makes foo(a:=1, c:=3, 2); undefined. The other method is as @mhasel said we could say all parameters are in order as soon as one of the parameters is not formal. This makes foo(a:=1, c:=3, 2); equivalent to foo(a:=1, b:=3, c:=2); where if the user ignores the warning/error we provide is very wrong. I'm fine with both approaches but I would add the information in the book about how this behaves. I would also add it in the error description once #826 is done.

ghaith avatar Nov 24 '23 07:11 ghaith