Pelles C > Bug reports

StringCbPrintf weirdness

(1/2) > >>

algernon_77:
Quite frankly, don't know if this is a bug or it's just me.. tried to run something like


--- Code: ---TCHAR   buf[64];
TCHAR   msg1[] = TEXT("msg1");
TCHAR   msg2[] = TEXT("msg2");

StringCbPrintf ( buf, ARRAYSIZE(buf), TEXT("%s %s"), msg1, msg2 );

--- End code ---

..and if I define UNICODE I get:

warning #2234: Argument 4 to 'StringCbPrintfW' does not match the format string; expected 'char *' but found 'wchar_t *'.
warning #2234: Argument 5 to 'StringCbPrintfW' does not match the format string; expected 'char *' but found 'wchar_t *'.

Trying to print buf (with a MessageBox), it seems as if StringCbPrintfA is called instead (only the first byte from each string is printed, because being a widechar, the other is 0).

I have Pelle 10.
I don't have any more ideas :)

frankie:
This isn't a bug.
The printf() specifier "%s", not like MS compiler, requires the long flag for unicode strings "%ls". This behavior is due to strict compliance to the standard of PellesC compiler (notoriously the MS compiler isn't compliant at all...  ::)).
So if you compile as ascii there are no errors, but if you compile for UNICODE you'l get the error.
There are 2 possible solutions, first if you add the long specifier will correct the error, but it will come out again compiling without UNICODE, the second is to automatically modify the specifier depending on the compilation. I.E:

--- Code: ---#if defined(UNICODE) || defined(_UNICODE)
#define STR_SPEC "ls"
#else
#define STR_SPEC "s"
#endif
 ....
    TCHAR   buf[64];
    TCHAR   msg1[] = TEXT("msg1");
    TCHAR   msg2[] = TEXT("msg2");

    StringCbPrintf ( buf, ARRAYSIZE(buf), TEXT("%") TEXT(STR_SPEC) TEXT(" %") TEXT(STR_SPEC), msg1, msg2 );

--- End code ---

algernon_77:
Yes, that's it  :)  :)
Thanks a lot!

I peered so much inside strsafe.h that my eyes hurt, lol. But it payed off in the end, I found a few errors (I think):

- inside StringGetsWorkerW, line 120, *pszDest = '\0'; should be *pszDest = L'\0'; ?
- inside _StringExHandleOtherFlagsA, line 463, *pszDestEnd = L'\0'; should be *pszDestEnd = '\0'; ?
- inside StringCchPrintfW, line 1061, *pszDest = '\0'; should be *pszDest = L'\0'; ?
- inside StringCbVPrintfW, line 2038, *pszDest = '\0'; should be *pszDest = L'\0'; ?

Thanks again!

frankie:

--- Quote from: algernon_77 on August 21, 2020, 03:54:40 PM ---Yes, that's it  :)  :)
Thanks a lot!

I peered so much inside strsafe.h that my eyes hurt, lol. But it payed off in the end, I found a few errors (I think):

- inside StringGetsWorkerW, line 120, *pszDest = '\0'; should be *pszDest = L'\0'; ?
- inside _StringExHandleOtherFlagsA, line 463, *pszDestEnd = L'\0'; should be *pszDestEnd = '\0'; ?
- inside StringCchPrintfW, line 1061, *pszDest = '\0'; should be *pszDest = L'\0'; ?
- inside StringCbVPrintfW, line 2038, *pszDest = '\0'; should be *pszDest = L'\0'; ?

Thanks again!

--- End quote ---
You're welcome.
Strictly speaking yes it would be better to prefix wide chars constants with the 'L' prefix, but in the specific case, value==0, is irrelevant because the char value is converted to 16bits wide char signed int with the same value. In C any value==0 is considered equivalent.

algernon_77:
Aha, I see now. I was under the impression that if you assign '\0' to a widechar, only one byte would get the value.
Regards!

Navigation

[0] Message Index

[#] Next page

Go to full version