Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#1728 swprintf is missing with -std=c99

WSL
closed
Earnie Boyd
None
Bug
duplicate
Duplicate
False
2014-05-17
2010-05-13
Peter Reese
No

test.c:
#include <stdio.h>
#include <wchar.h>

int main(int argc, char *argv[]){
wchar_t wstr[100],
test1[] = L"test1",
test2[] = L"test2";

swprintf(wstr, 100, L"%ls %ls", test1, test2);
wprintf(L"%ls", wstr);
return 0;
}

gcc -std=c99 test.c -o test.exe
test.c: In function `main':
test.c:9: warning: implicit declaration of function `swprintf'

gcc test.c -o test.exe
test.c: In function `main':
test.c:9: warning: passing arg 2 of `swprintf' makes pointer from integer without a cast

With DMC it compiles and executes fine.

Discussion

  • Earnie Boyd
    Earnie Boyd
    2013-02-12

    Ticket moved from /p/mingw/support-requests/124/

    Can't be converted:

    • _priority: 5
     
  • Earnie Boyd
    Earnie Boyd
    2013-02-12

    • status: open --> pending
    • assigned_to: Earnie Boyd
    • milestone: --> WSL
    • type: --> Bug
    • resolution: --> later
    • category: --> Unknown
    • patch_attached: --> False
     
  • Earnie Boyd
    Earnie Boyd
    2013-02-12

    • labels: mingw runtime --> duplicate?
     
  • Earnie Boyd
    Earnie Boyd
    2013-02-19

    • labels: duplicate? -->
    • status: pending --> closed
    • resolution: later --> duplicate
    • category: Unknown --> Duplicate
     
  • Earnie Boyd
    Earnie Boyd
    2013-02-19

  • I have this example.c

    #include <stdio.h>
    int main() {
        wchar_t wstr[10];
        swprintf( wstr, L"hallo" );
        wprintf(wstr);
        return 0;
    }
    


    Compiled with MinGW 4.8.1.
    It's ok as GNU dialect
    gcc example.c -std=gnu99   or   gnu11

    Instead compiled as ISO C
    gcc example.c -std=c99   or   c11

    warning: implicit declaration of function 'swprintf'



    Looking for a solution I applied to stdio.h the patch provided at #1807.
    Then compiling as both GNU or ISO C

    warning: passing argument 2 of 'swprintf' makes integer from pointer without a cast

    because patch doesn't support

    swprintf (wchar_t*, const wchar_t*, ...)
    

    but only

    swprintf (wchar_t*, size_t, const wchar_t*, ...)
    



    How can I compile example.c as ISO C ?



    Enlightenment
    ISO C Standard requires the second size_t parameter.
    See for example Standardness of swprintf.

     
    Last edit: Michele Salvador 2014-05-16
  • Keith Marshall
    Keith Marshall
    2014-05-16

    For clarification, (as I think you've probably realized already) ...

    How can I compile example.c [with old Microsoft prototype swprintf()] as ISO C ?

    You can't. ISO-C99 section 7.24.2.3 specifies, (and POSIX agrees), that the swprintf() function prototype is:

    Synopsis
    
    #include <wchar.h>
    int swprintf(wchar_t * restrict s,
    size_t n,
    const wchar_t * restrict format, ...);
    

    Thus, to compile as ISO-C, you must correct your code, to call the function in accordance with the specified prototype.

    MSDN claims that the MSVC implementation has been brought into line with the ISO-C standard, and that the old behaviour is deprecated. However, Earnie's comments on [#2018] would suggest otherwise; I don't know what the status of his "fix", associated with that ticket, may be, (and he seems to be unavailable to comment at the moment), so, if you can avoid using swprintf() in the first instance, that may be preferable. If you persist with it, the results may not be entirely predictable.

     

    Related

    Issues: #2018

  • Ok. I corrected

    swprintf( wstr, L"hallo" );
    

    adding the number of characters as second argument

    swprintf( wstr, sizeof wstr / sizeof(wchar_t), L"hallo" );
    

    This one compiled with MinGW 4.8.1 as   -std=c99   or   c11   gives

    warning: implicit declaration of function 'swprintf'

    and as   -std=gnu99   or   gnu11

    warning: passing argument 2 of 'swprintf' makes pointer from integer without a cast


    The patch.diff posted at #1807 allows to compile properly as ISO-C.
    Instead warning remains the same compiled as GNU (not a problem for me).

    I didn't try the patch at #2018.

    Thank you!

     
    • Keith Marshall
      Keith Marshall
      2014-05-17

      As I said previously, I strongly recommend that you avoid swprintf() entirely; try using _snwprintf() instead.

      The problem is that, in spite of MSDN's claims to the contrary, Microsoft's implementation of swprintf() does not conform, in any shape or form, to ISO-C standards. MinGW's old header files recognized this, and declared a prototype to match the actual implementation; this prototype is occluded when you compile with any option which stipulates any ISO-C standards conformance, because you cannot use Microsoft's broken implementation in a conforming application.

      When you try to gerrymander the headers, to specify an ISO-C conforming prototype, (which is what [#2018] does), all you are doing is creating a mismatch between declared prototype and implementation; as Earnie's test case, attached to [#2018] demonstrates, this will cause your application to crash, with a segmentation fault -- Microsoft call it an access violation. Furthermore, whatever [#2018] may claim, it does not fix this; the effect of crashing the calling application persists.

      The bottom line is that you simply cannot use swprintf() in a MinGW application, if you insist on compiling for ISO-C conformity; you must use the old MinGW prototype, and to get that you must use a version of the header files which does not attempt to declare the ISO-C prototype, and you must not attempt to stipulate ISO-C conformity, (whether that be to -std=c99, or to any other level of ISO-C standard).

       

      Related

      Issues: #2018