Microsoft _stprintf warning - c++

Why I get the following warning for the following code :)
Code:
_stprintf(m_szFileNamePath,_T("%s"),strFileName);
warning C4996: '_swprintf': swprintf has been changed to conform with the ISO C standard, adding an extra character count parameter. To use traditional Microsoft swprintf, set _CRT_NON_CONFORMING_SWPRINTFS.
I know _strprintf is a macro which if _UNICODE is defined will evaluate to _swprintf else it will be sprintf.
Now what is this _swprintf. There is a function swprintf, but why is _stprintf evaluating to _swprintf instead of swprintf.
What is the difference b/w the _xxx and xxx functions?
EDIT:
Okay there are two definitions for the UNICODE version of _stprintf, which one is included?
The one in tchar.h or strsafe.h?

http://msdn.microsoft.com/en-us/library/ybk95axf%28VS.80%29.aspx
swprintf is a wide-character version of sprintf; the pointer arguments to swprintf are wide-character strings. Detection of encoding errors in swprintf may differ from that in sprintf. swprintf and fwprintf behave identically except that swprintf writes output to a string rather than to a destination of type FILE, and swprintf requires the count parameter to specify the maximum number of characters to be written. The versions of these functions with the _l suffix are identical except that they use the locale parameter passed in instead of the current thread locale.
In Visual C++ 2005, swprintf conforms to the ISO C Standard, which requires the second parameter, count, of type size_t. To force the old nonstandard behavior, define _CRT_NON_CONFORMING_SWPRINTFS. In a future version, the old behavior may be removed, so code should be changed to use the new conformant behavior.

Maybe this?
_stprintf(m_szFileNamePath, 256, _T("%s"), strFileName);

Microsoft provides its own extension of CRT _swprintf - is not compatible (for example) with unix

Microsoft (used to?) prefix otherwise widely available non-win32 functions that were not part of the C standard with underscore.

This should work
int len = swprintf( buf, 100, L"%s", L"Hello world" );

Related

Inconsistent return from std::isblank between Visual C++ and gcc. Which one is wrong?

I'm seeing inconsistent behavior in a call to std::isblank between Visual C++ on Windows and gcc on Ubuntu and I'm wondering which one is correct.
On both compilers -- when the default locale is the "C" locale -- the following call returns false
std::isblank('\n');
This is what I expect. And it squares with what I see on cppreference.com
In the default C locale, only space (0x20) and horizontal tab (0x09)
are classified as blank characters.
However with C++, we also have the version that takes a std::locale argument
std::isblank('\n', std::locale::classic());
Here I am supplying std::locale::classic. Shouldn't that be the equivalent to the previous call? Because when I call this second version on Windows, it returns true. It considers a newline to be a blank character. Linux still says false.
Is my understanding (about std::locale::classic) correct? And if so, is the Visual C++ version wrong?
Yes, MSVS is wrong. [locale.statics] states:
static const locale& classic();
The "C" locale.
Returns: A locale that implements the classic "C" locale semantics, equivalent to the value locale("C").
Remarks: This locale, its facets, and their member functions, do not change with time.
Thus the following:
std::isblank('\n', std::locale::classic());
Is the same as:
std::isblank('\n');
Where locale("C") has been called.

Strcpy parameters are not correct

I am updating an older visual studio project to VS2013 and keep running into an issue where it does not like the parameters that I pass into strcpy functions.
This is a Unicode application.
I get the error -
cannot convert argument 2 from 'CString' to 'const char *'
strcpy(szFileName, m_strFileName);
m_strFileName is defined as a CString.
The strcpy function accepts only parameters of type char*. That's what the compiler error is telling you—you have a type mismatch error. In a Windows environment, char* means narrow (i.e., ANSI) strings. Which no one uses anymore and hasn't for well over a decade.
You know this already; you say that you're building a Unicode application, which is what you should be doing. But that means you can't call the narrow string functions (str*) anymore. You have two options. Either:
Explicitly call the "wide" (i.e., Unicode) variants of the C string library functions, which are prefixed with wcs instead of str. In this case, then, you'd be calling wcscpy.
Use the macros that map automatically to the correct variant of the C string library functions. If the _UNICODE symbol is defined (as it would be for you), they will map to the wide-string variants; otherwise, they map to the narrow-string variants. These functions (actually macros) are all prefixed with _tcs. In this case, then, you'd call _tcscpy.

"wcs" and "_w" and "_mbs" prefix in Visual Studio

I am a little confused with respect to the difference in the functions which are defined with/without the wcs/_w/_mbs prefix.
For Example:
fopen(),_wfopen()
On msdn it is given that:
The fopen function opens the file that is specified by filename.
_wfopen is a wide-character version of fopen; the arguments to _wfopen are wide-character strings. Otherwise, _wfopen and fopen behave
identically.
I just had a doubt whether there is any platform dependence to windows associated with the addition of the "_w" prefix.
strcpy(),wcscpy(),_mbscpy()
On msdn it is given that:
wcscpy and _mbscpy are, respectively, wide-character and multibyte-character versions of strcpy.
Again there is a doubt if the addition of "wcs" or "_mbs" is platform dependent.
EDIT:
Is WideCharToMultiByte function also platform dependent?
WideCharToMultiByte is not a C Runtime function, it's a Windows
API,hence it is platform dependent
Similarly is wcstombs_s function also platform dependent?
It was nonstandard but was standardized in C11 Annex K.
The wcs* functions like wcscpy are part of the C Standard Library. The _wfopen function and other _w* functions are extensions, as are the multibyte string functions like _mbscpy.
For the most part, Visual C++ C Runtime (CRT) functions that have a leading underscore are extensions; functions that do not have a leading underscore are part of the C Standard Library.
There are two main exceptions, where extensions may not have leading underscores:
There are several extension functions, declared with an underscore prefix, that have prefixless aliases for backwards source compatibility. These aliases are deprecated, and if you try to use them you'll get a suppressable deprecation warning (C4996).
There are _s-suffixed secure alternative functions to some C Standard Library functions, e.g. scanf_s. These are declared by default, but their declarations may be suppressed by defining the macro __STDC_WANT_SECURE_LIB__ to have the value 0.
(These functions were actually added to C11 in the optional Annex K,
but note that there are a few differences between what is specified
in the C Standard and what is implemented by Visual C++. The
differences are due to a historical
accident.)
wcscpy is standard. _mbcscpy is specific to MS VC.
That's why there is an underscore at the start: names with leading underscore are reserved for implementation-specific things.

-Werror=format: how can the compiler know

I wrote this intentionally wrong code
printf("%d %d", 1);
compiling with g++ and -Werror=format.
The compiler gives this very impressive warning:
error: format '%d' expects a matching 'int' argument [-Werror=format]
As far as I can see, there's no way the compiler can tell that the code is wrong, because the format string isn't parsed until runtime.
My question: does the compiler have a special feature that kicks in for printf and similar libc functions, or is this a feature I could use for my own functions? String literals?
As far as I can see, there's no way the compiler can tell that the code is wrong, because the format string isn't parsed until runtime.
As long as the format string is a string literal, it can be parsed at compile time. If it isn't (which is usually a bad idea anyway), then you can get a warning about that from -Wformat-security.
does the compiler have a special feature that kicks in for printf and similar libc functions?
Yes.
or is this a feature I could use for my own functions?
Yes, as long as you're using the same style of format string as printf (or various other standard functions like scanf or strftime).
void my_printf(Something, char const * format, SomethingElse, ...)
__attribute__ ((format (printf,2,4)));
to indicate that the second argument is a printf-style format string, and the values to format begin with the fourth. See http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html.
Well, printf definitely parses the format string at runtime in order to do its job. But nowhere is it written that the compiler may not choose to parse it itself if it wants to.
The documentation for -Wformat says that this is exactly what happens:
-Wformat
-Wformat=n
Check calls to printf and scanf, etc., to make sure that the arguments supplied have > types appropriate to the format string
specified, and that the conversions specified in the format string
make sense. This includes standard functions, and others specified by
format attributes (see Function Attributes), in the printf, scanf,
strftime and strfmon (an X/Open extension, not in the C standard)
families (or other target-specific families). Which functions are
checked without format attributes having been specified depends on the
standard version selected, and such checks of functions without the
attribute specified are disabled by -ffreestanding or -fno-builtin.
The formats are checked against the format features supported by GNU libc version 2.2.
These include all ISO C90 and C99 features, as
well as features from the Single Unix Specification and some BSD and
GNU extensions. Other library implementations may not support all
these features; GCC does not support warning about features that go
beyond a particular library's limitations. However, if -Wpedantic is
used with -Wformat, warnings are given about format features not in
the selected standard version (but not for strfmon formats, since
those are not in any version of the C standard). See Options
Controlling C Dialect.
Update: Turns out you can use it on your own functions. Mike has the details.

strdup or _strdup?

When I use strdup in Microsoft Visual C++, it warns me:
warning C4996: 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strdup. See online help for details.
Thus it seems _strdup is correct.
But when I use _strdup in GCC (Fedora Linux OS), the compiler shows an error:
error: ‘_strdup’ was not declared in this scope
With GCC and Linux, compiler does not show any error for strdup.
Which is correct - strdup or _strdup?
Note: I include <string.h> in my code.
Which is correct?
strdup is a perfectly correct POSIX function. Nevertheless, it doesn't belong to the standard, and the ANSI C standard reserves some (broad) classes of function names for further use. Among these, there are
Function names that begin with str and a lowercase letter
therefore, the MS guys decided to replace strdup with _strdup.
I'd just continue using strdup. It's unlikely the C committee will define strdup to something else than POSIX. Either #define strdup _strdup or silence the warning.
BTW I hope you see this applies to your functions with names like string_list etc., too.
strdup is not a standard C++ function. but it is apparently a Posix function, and anyway it's a well known function which has been there since K&R C. so if you absolutely must use it, do not fret about any possible name collision, and just write strdup for maximum portability.
You can #define _CRT_NONSTDC_NO_DEPRECATE to disable this warning.
If you just want to avoid the Warning message:
Project-> property -> C/C++ -> Preprocessor -> Preprocessor Definitions
Edit this, and add
_CRT_NONSTDC_NO_DEPRECATE
strdup is POSIX:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/strdup.html
_strdup is Windows specific:
http://msdn.microsoft.com/en-us/library/y471khhc(v=vs.80).aspx
On Unix, use strdup. On Windows, use _strdup. It's that simple. If you need to write portable code between Unix and Windows:
use system dependent macros (for example _WIN32 vs. _POSIX_VERSION) to select the proper function (but notice that the macros may depend on specific pre existing include files):
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html
http://msdn.microsoft.com/en-us/library/b0084kay(v=vs.80).aspx
use standard functions to reimplement strdup: strlen, malloc and memmove.
use a cross platform utility library, like glib:
http://developer.gnome.org/glib/2.28/glib-String-Utility-Functions.html#g-strdup
Note that Visual C++ message suggests that _strdup belongs to the C++ standard, but this is false, as it can be verified on the C++ standard. It merely uses the underscore prefix as a "namespace" for the function.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3376.pdf
Don't know about C++.
The C Standard does not describe any function with the strdup name (though the name is reserved).
To be portable, in C, you're better off replacing that with malloc, strcpy, and free.
it's not a warning but an error reported in higher version of vs.
use macro #ifdef WIN32 to switch