Sign in to follow this  
programci_84

Killing compiler warnings?

Recommended Posts

Hi, I'm coding in Visual C++ 2008 Express and using some functions like strcpy, sprintf, fprintf etc. But compiler gives me a lot of silly "warnings" in the output window because of using'em. It also says "To disable deprecation, use _CRT_SECURE_NO_WARNINGS." at the end of warning lines. Where should I use that _CRT_SECURE_... or how can I kill these warnings? Thanks in advance.

Share this post


Link to post
Share on other sites
You can just #define _CRT_SECURE_NO_WARNINGS in your code (somewhere before those functions are used), or #pragma warning(disable: error_code) them.

But really you should try to use the safe versions of those functions (they are generally mentioned in the warning messages if I recall correctly), or even better yet, use actual C++ (std::string and std::cout).

Share this post


Link to post
Share on other sites
#define _CRT_SECURE_NO_WARNINGS. Or better yet, add it to preprocessor definitions in project's preprocessor settings.

Quote:
the best way to get rid of these warings if to not use strcpy, sprintf, fprintf etc...


Which isn't an option since this problem is mostly relevant to C-based code, or C-based APIs.

Quote:
Prefer the "safer" versions of these functions,


IMHO, no. MS is trying to patch wrong holes. The C standard functions are as standardized as it gets (not too much, but developers know what to expect), where as 'safer' versions are MS specific.

Share this post


Link to post
Share on other sites
Quote:


IMHO, no. MS is trying to patch wrong holes. The C standard functions are as standardized as it gets (not too much, but developers know what to expect), where as 'safer' versions are MS specific.


MS are patching known security issues with the C standard functions. You are not forced to use them, you can completely ignore them with a simple #define, so where's the problem ?

Share this post


Link to post
Share on other sites
Quote:
Original post by MrMark
Quote:


IMHO, no. MS is trying to patch wrong holes. The C standard functions are as standardized as it gets (not too much, but developers know what to expect), where as 'safer' versions are MS specific.


MS are patching known security issues with the C standard functions. You are not forced to use them, you can completely ignore them with a simple #define, so where's the problem ?


For some of these, there were already standardized versions for some things, such as snprintf, in C99, so it's unclear why MS felt the need to create sprintf_s and snprintf_s. The annoyance people have is that not everyone realizes that these methods are non-standard (I've worked with two coworkers who assumed that everything in the CRT was standard) and become a potential mess if you are interested in portability. Giving warnings for standards-compliant code and saying that it's deprecated is misleading, at best. It's semantics, but potentially very important semantics.

Share this post


Link to post
Share on other sites
Quote:
Original post by Rydinare
For some of these, there were already standardized versions for some things, such as snprintf, in C99, so it's unclear why MS felt the need to create sprintf_s and snprintf_s. The annoyance people have is that not everyone realizes that these methods are non-standard (I've worked with two coworkers who assumed that everything in the CRT was standard) and become a potential mess if you are interested in portability. Giving warnings for standards-compliant code and saying that it's deprecated is misleading, at best. It's semantics, but potentially very important semantics.
I would think the reasoning is obvious: sprintf_s works differently to snprintf. snprintf will not NULL-terminate the destination buffer if it overflows, while sprintf_s does. snprintf_s does the same thing, but it has the added "stop after this many characters" parameter that snprintf has.

Another example is strncat vs. strcat_s. In strncat you pass the maximum number of characters to copy. In strcat_s, you pass the size of the destination buffer. The point is simplicity: with the _s versions, the second parameter is always the size of the destination buffer. With the non-_s versions, you usually have to pass the "maximum number of characters to copy, oh and by the way, don't forget to the NULL terminate the destination buffer when you're done".

I agree that saying the non-_s versions are "deprecated" is perhaps misleading, but the fact is, they should be!

Share this post


Link to post
Share on other sites
Quote:
Original post by Codeka
I would think the reasoning is obvious: sprintf_s works differently to snprintf. snprintf will not NULL-terminate the destination buffer if it overflows, while sprintf_s does. snprintf_s does the same thing, but it has the added "stop after this many characters" parameter that snprintf has.

This is true for the Microsoft implementation, but I believe an actual implementation that conforms to the C99 spec says that 1) the n'th character will be the \0 terminator (where n is the size of the output string you pass in), and 2) if the output is truncated, the return value will be the number of characters that would have been written (not including the terminator) had the output string been long enough or -1 if an error occurred.

The second issue alone I have seen the Microsoft version of snprintf not conform to at all, which bit me in the ass a while back when having to write some C code. And in fact I believe I've seen a bug report somewhere on MSDN someone filed regarding the second issue where the MS developer basically said they wouldn't be fixing this behavior anytime in the foreseeable future. So basically, while you should be able to rely on snprintf to always terminate and provide the correct return value, if your developing on Windows, and you rely on this functionality, you basically have to either provide your own version that provides the right behavior or just use one of their platform specific versions that does the right thing if they exist.

Share this post


Link to post
Share on other sites
Quote:
Original post by romer
Quote:
Original post by Codeka
I would think the reasoning is obvious: sprintf_s works differently to snprintf. snprintf will not NULL-terminate the destination buffer if it overflows, while sprintf_s does. snprintf_s does the same thing, but it has the added "stop after this many characters" parameter that snprintf has.

This is true for the Microsoft implementation, but I believe an actual implementation that conforms to the C99 spec says that 1) the n'th character will be the \0 terminator (where n is the size of the output string you pass in)


Hmm, good point, I didn't know that (shows what a limited world I live in [wink]).

Anyway, my point about strncat vs. strcat_s still stands at least. But then that wasn't the point that Rydinare was making, either.

Share this post


Link to post
Share on other sites
Quote:
Original post by Codeka
Quote:
Original post by romer
Quote:
Original post by Codeka
I would think the reasoning is obvious: sprintf_s works differently to snprintf. snprintf will not NULL-terminate the destination buffer if it overflows, while sprintf_s does. snprintf_s does the same thing, but it has the added "stop after this many characters" parameter that snprintf has.

This is true for the Microsoft implementation, but I believe an actual implementation that conforms to the C99 spec says that 1) the n'th character will be the \0 terminator (where n is the size of the output string you pass in)


Hmm, good point, I didn't know that (shows what a limited world I live in [wink]).

Anyway, my point about strncat vs. strcat_s still stands at least. But then that wasn't the point that Rydinare was making, either.


Well to be honest, it's rare that I have to use any of these methods. It's usually only if I'm interfacing with someone else's code and they're chosen to make their API low level. My preference is to use STL whenever possible, because it makes life easier while adding only minimal overhead. My perception is still that at a minimum, the warnings they give should be changed to be less confusing, and offer the alternatives, but be clear that the alternatives will only exist on Microsoft platforms. I also think all of their extensions should be in a separate library that isn't linked by default or at least be prefaced with underscores (although frankly, a lot of developers don't realize that the underscores mean that it's an extension).

I mean to be fair, why don't Win32 methods like IsBadReadPtr and IsBadWritePtr throw up blatant warnings when they're used? They are known well-intentioned methods with drastic side effects, yet no warnings for those. Just an example which seems to add some doubt as to MS's motives.

To be fair, I will grant you that the C++ standards committee moves ridiculously slow, so from that side of things there's a little bit of forgiveness for MS. MS's approaches are fine once you know the downsides to what they've chosen and can work around it; but truthfully, most developers don't do this level of research and wind up rewriting everything once they have to port or jumping to the wrong conclusion (see the many "STL is slow" threads). It's unfortunate that MS chooses misleading approaches that will cause headaches when portability is required. I think that's most people's gripe when they are annoyed. I doubt it's truly malicious, I think it's just more of the "we're Microsoft and we can do what we want", even though I don't think they always fully take into account the ramifications for developers. But that's just my 2 cents.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this