2

This is not a duplicate as you might think in first look.

The strcpy() deprecation in Visual Studio is already known for a few years, as a difficulty when you try to port your C code from GCC to MSVC.

In Visual Studio 2013, all the workarounds of defining _CRT_SECURE_NO_WARNINGS fail to solve the issue - the compilation is still failing on this error (It is called "warning", but it is actually an error that causes the compilation to fail).

My question is whether there is an elegant way to solve it within the code?

For example, such a macro would help me a lot:

#ifdef SOMETHING_THAT_INDICATES_ITS_MSVC_COMPILER
    Some macro that makes the following substitution:
        strcpy(dest, src) -> strcpy_s(dest, strlen(src), src)
#endif

Could you please tell me:

  • If you think it is a good approach to solve this portability issue?
  • How to correctly write such a macro?
  • Any other recommendations?
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
SomethingSomething
  • 11,491
  • 17
  • 68
  • 126
  • 1
    Define `_CRT_SECURE_NO_WARNINGS` and go. – i486 Jun 16 '15 at 14:03
  • I wrote here that it does not work in VS2013. DId you try it? – SomethingSomething Jun 16 '15 at 14:04
  • 1
    `strlen(src)` should be `strlen(src)+1` – BLUEPIXY Jun 16 '15 at 14:09
  • 3
    `_CRT_SECURE_NO_WARNINGS` works fine for me in VS2013. Make sure you define it in your precompiled header or in your project settings under `C/C++::Preprocessor`. – uesp Jun 16 '15 at 14:12
  • Put it in project preprocessor definitions - then it works. It is true that simple `#define _CRT_SECURE_NO_WARNINGS` does not work...(?!) – i486 Jun 16 '15 at 14:20
  • 1
    Put in `_CRT_SECURE_NO_WARNINGS` as said earlier, or put it in stdafx.h and rebuild. Ignore Microsoft's recommendations. – Barmak Shemirani Jun 16 '15 at 15:05
  • 1
    [Everyone please read this](http://stackoverflow.com/questions/23486938/c4996-function-unsafe-warning-for-strcpy-but-not-for-memcpy/23490019#23490019) before making any unintelligent Microsoft comments about strcpy being unsafe. – Lundin Jun 16 '15 at 15:08
  • @BarmakShemirani You should post that as the correct answer, it would be very helpful as this question seems to pop up somewhat frequently. – Lundin Jun 16 '15 at 15:10
  • Actually someone posted an answer like that in the post I linked so I'm guessing this is a duplicate after all. @SomethingSomething if you don't get it working by modifying stdafx please drop a comment here and I'll re-open. Nothing wrong with the question after all, it's a good one. – Lundin Jun 16 '15 at 15:11
  • I don't want the `stdafx.h` solution. I don't expect all my library users to start patching their compiler just for my lib – SomethingSomething Jun 17 '15 at 05:44
  • @uesp - doesn't work when you define it in the first line of all the headers in the project. I think I'll finally implement my own `strcpy` – SomethingSomething Jun 17 '15 at 11:14

2 Answers2

2

If src is not properly terminated, this will crash, also if dst is too short for src - which is the reason to use strcpy_s() actually. You have to take the shortest size of source (- 1) and destination. However, as these mostly come from pointers, the length information is not available anymore.

A proper (and portable) solution would be to fix the affected code to use strcpy_s() properly. A hackish solution might be to simply pass a length value to strcpy_s() larger than any string might have, e.g. RSIZE_MAX, which is the max. allowed length. That would be no more or less secure than strcpy() or your approach. Disclaimer: I strongly discourage from doing so! Get the code right instead!.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
2

The macro that you suggested uses strcpy_s in an unsafe way, i.e. as if it were a strcpy. The reason the use is unsafe is that the second parameter is meant to represent the length of the destination, not the length of the source. If the source is long enough to cause memory overrun, strcpy_s is not going to help.

Your approach could work as a way to silence the compiler, but the deprecation is there for a reason: strcpy is unsafe, so you should make an effort to use strcpy_s instead.

Going at it from the other end would be better: instead of defining a macro that dresses strcpy as strcpy_s on MSVC, define a macro in gcc to dress up strcpy_s as strcpy to maintain portability.

To achieve this, go through your source code, and replace all uses of strcpy with strcpy_s, passing the size of the destination as the second parameter. Then conditionally define a macro that converts strcpy_s to strcpy by dropping the middle parameter on gcc, write your own strcpy_s or borrow someone else's implementation on gcc.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523