There is no guess. As long as a string constant does not contain any characters that require a WideChar (and the UnicodeStrings modeswitch is not enabled) then a PAnsiChar is preferred to a PWideChar.That's fine but, the compiler should let the programmer know by a warning or at least a hint that PAnsiChar is preferred over PWideChar because there are situations like the one above where that "preference" leads to undesirable results.
swprintf is a wide-character version of sprintf; the pointer arguments to swprintf are wide-character strings.To me it seems as if an overload for an ansichar pointer version is not provided (at least in the standard C runtime).
There is no guess. As long as a string constant does not contain any characters that require a WideChar (and the UnicodeStrings modeswitch is not enabled) then a PAnsiChar is preferred to a PWideChar.That's fine but, the compiler should let the programmer know by a warning or at least a hint that PAnsiChar is preferred over PWideChar because there are situations like the one above where that "preference" leads to undesirable results.
That preference is just a built-in guess in the compiler.
Do you have documentation for the NTdll version of swprintf which mentions that an ansichar pointer parameter is supported? The Visual Studio 2019 documentation (https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/sprintf-sprintf-l-swprintf-swprintf-l-swprintf-l?view=msvc-160) mentions this:Yes, I do have documentation for that. Specifically, sprintf allows a "%S" (capital S) to indicate that the parameter is a null terminated sequence of widechar(s). Likewise, swprintf allows a "%S" to indicate that the parameter is a null terminated ansi (single byte) sequence of characters.Quoteswprintf is a wide-character version of sprintf; the pointer arguments to swprintf are wide-character strings.To me it seems as if an overload for an ansichar pointer version is not provided (at least in the standard C runtime).
There will not be a warning for this.That's very unfortunate because there definitely should be one. The code is absolutely correct yet, it doesn't work because the compiler made a decision behind the programmer's back and, you're saying the compiler shouldn't inform the user of that fact. When the compiler makes decisions behind the programmer's back, the least it should do is to let the programmer know.
There will not be a warning for this.That's very unfortunate because there definitely should be one. The code is absolutely correct yet, it doesn't work because the compiler made a decision behind the programmer's back and, you're saying the compiler shouldn't inform the user of that fact. When the compiler makes decisions behind the programmer's back, the least it should do is to let the programmer know.
Thanks for clarifying what is available. This means that there isn't an overloaded function in the library/dll, the type of the string pointer is interpreted according to the format string?Do you have documentation for the NTdll version of swprintf which mentions that an ansichar pointer parameter is supported? The Visual Studio 2019 documentation (https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/sprintf-sprintf-l-swprintf-swprintf-l-swprintf-l?view=msvc-160) mentions this:Yes, I do have documentation for that. Specifically, sprintf allows a "%S" (capital S) to indicate that the parameter is a null terminated sequence of widechar(s). Likewise, swprintf allows a "%S" to indicate that the parameter is a null terminated ansi (single byte) sequence of characters.Quoteswprintf is a wide-character version of sprintf; the pointer arguments to swprintf are wide-character strings.To me it seems as if an overload for an ansichar pointer version is not provided (at least in the standard C runtime).
IOW, both sprintf and swprintf can take either wide character or single character parameters, it only depends on the format specifier.
Also, that capability _is_ present in the standard C runtime library and it is documented (in the supported format specifiers.)
There are potentially numerous implicit type conversions applied by the compiler, if the compiler should mention each one it would be more than useless as it will swamp the compiler messages and hide the really important messages.There will not be a warning for this.That's very unfortunate because there definitely should be one. The code is absolutely correct yet, it doesn't work because the compiler made a decision behind the programmer's back and, you're saying the compiler shouldn't inform the user of that fact. When the compiler makes decisions behind the programmer's back, the least it should do is to let the programmer know.
There are potentially numerous implicit type conversions applied by the compiler, if the compiler should mention each one it would be more than useless as it will swamp the compiler messages and hide the really important messages.
Thanks for clarifying what is available. This means that there isn't an overloaded function in the library/dll, the type of the string pointer is interpreted according to the format string?You're welcome and, that is correct. There cannot be an overload because the "..." is generic, it has no associated type. Their type will be determined/interpreted according to the format specifier(s) (which better be correct or else... )
With no further information given to the compiler, why do you think it is wrong to pick the most compact and exact representation of the string literal and choose the provided overload that matches this?because the case is ambiguous and whatever decision the compiler makes, may or may not be right. In those cases, the least the compiler should do is to let the programmer know that it made a decision which is _not_ guaranteed to be correct. It is the fact that the decision is potentially incorrect that justifies emitting a warning.
There are potentially numerous implicit type conversions applied by the compiler, if the compiler should mention each one it would be more than useless as it will swamp the compiler messages and hide the really important messages.But normally those conversions are deterministic. IOW, the compiler can figure out what is unambiguously correct. Whenever the compiler doesn't know the answer it's supposed to rely on the programmer to determine what is correct. Compiler "preferences" cannot be used to justify a choice that may or may not be correct. That's the programmer's job but, the programmer relies on the compiler to tell him/her where it made a decision not based on correctness but on "preference".
When editing the source a programer hit key "(" after "swprintf" and codetools code completion displays available overloaded versions. This is enough to use the needed one.
When editing the source a programer hit key "(" after "swprintf" and codetools code completion displays available overloaded versions. This is enough to use the needed one.No, that's incorrect. The selection of the correct overload is determined by the _format specifier_ not by the function parameters.
it is responsibility of programmers to prepare proper parameters to use exactly needed version of the functions.Yes and, it is the compiler's responsibility to inform the programmer of ambiguous choices it made which it has no way of knowing are correct.
There is no need to establish some kind of cooperation between codetools code completion Authors and FPC core Team - code completion is showing my or anyone programer's code used for function declarations. So, it is responsibility of programmers to prepare proper parameters to use exactly needed version of the functions.
Specifically, if the format specifier had been "%S" instead of "%s", your change would result in the call not producing the correct result.
The functions and parameters are entirely proper, and are accepted by the compiler without error, warning or other comment. That's the whole point of the thread.
@440bxNo, I am not kidding. That is precisely the point, the compiler cannot know what the correct overload is without inspecting the format specifier and it is completely unreasonable to expect the compiler to inspect the format specifier. The result is, the compiler cannot know whether it should pass a widechar or char string and, since it doesn't know, if it decides on one of them, it should inform the programmer of its guess (sometimes euphemistically referred to as "preference") because that guess has about a 50% chance of being wrong, which for a compiler is pretty bad.
You must be kidding - do you really think that FPC compiler Team will ever study internal (Windows API) formatting switches to decide which version of overloaded function is the needed one?
@WooBean: which of those is chosen? Why is it chosen? Can you guarantee that? Because one of the senior compiler team wouldn't be drawn beyond saying that it was implementation-defined.
MarkMLl
I see you are too busy to compile several lines example ... .
IMHO, the compiler should not be blamed for having difficulties interpreting an ambiguous statements. Overloaded subroutines can be the source of big frustration both for the compiler and the programmer. Ask somebody with at least a modest experience in C++ :)The compiler isn't to blame for ambiguous statements. What the compiler can legitimately be blamed for is making choices in situations that are not decidable and _not_ informing the programmer that it made an arbitrary choice that is not guaranteed in any way to be correct. THAT is the problem, the compiler's silence when it made a decision that is simply arbitrary (calling it a "preference" doesn't change the situation.)
@440bx
Isn't it better that way:
function swprintf_wc({ _out_ } OutWideBuffer : pwidechar; { _in_ } InFormatString : pwidechar; { _in_ } InWidechars : pwidechar) : integer; cdecl; external ntdll name 'swprintf'; function swprintf_c({ _out_ } OutWideBuffer : pwidechar; { _in_ } InFormatString : pwidechar; { _in_ } InAnsiChars : pchar) : integer; cdecl; external ntdll name 'swprintf';
BTW, It is more related to the functions of varargs than to overloaded ones, IMO they are mainly C language prerogative.
Regards,
The compiler isn't to blame for ambiguous statements. What the compiler can legitimately be blamed for is making choices in situations that are not decidable and _not_ informing the programmer that it made an arbitrary choice that is not guaranteed in any way to be correct. THAT is the problem, the compiler's silence when it made a decision that is simply arbitrary (calling it a "preference" doesn't change the situation.)
I think that everybody agrees that this is not an error situation. But it really does merit a note or warning.I think there is merit in knowing what the compiler finds acceptable and what it finally chooses. There is already some reporting build into the compiler around overload errors, so with a small tweak it is possible to get a list of feasible overloads followed by the specific overload chosen. Consider the following test case: