1

When I try to run the code i get:

warning: implicit declaration of function 'strcpy_s' [-Wimplicit-function-declaration]

I included string.h and stdio.h.

Code:

#include <string.h>
#include <stdio.h>

int main(void) {
    static int foo = 0;
    char s[12];
    char *t = "01234567890123"
    printf("foo %p\n s %p\n", &foo, s);
    strcpy_s(s, 11, t);
}
TheEagle
  • 5,808
  • 3
  • 11
  • 39
  • Welcome to [so]. Please take a [tour] of the site, read [ask] a good question and how to create a [mcve]. Then come back to your question and reformulate it (preferably with code samples, the provided input and the expected output) in order to get a (useful) answer. Before posting a question, [search](/search) the site and make sure a similar question wasn't already answered. Show what you have tried and where you got stuck to maximize the chances to get help. – axiac Jan 25 '21 at 17:46
  • In short, it's a function that your compiler "knows about", but you didn't include the right header for it. – Govind Parmar Jan 25 '21 at 17:46
  • 2
    Please never post images of text, copy-paste it *as text* into the question. Also please take some time to read [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). Lastly please learn how to [edit] your question. – Some programmer dude Jan 25 '21 at 17:46
  • 2
    Please **do not** post images of code, sample data, program output or error message. **The contents of a screenshot cannot be searched, run as code, or copied and edited to create a solution.** Select the code and use the copy-paste functionality of your OS to put it in the clipboard. Then [edit] the question and paste the code as text. Select the code in the question editor and press the `{}` button in the question editor toolbar to format it nicely. – axiac Jan 25 '21 at 17:46
  • 1
    Is "vsc" supposed to mean "Visual Studio Code"? Please add the appropriate tag. – John Bollinger Jan 25 '21 at 17:48
  • If indeed you are talking about Visual Studio Code, then what is the underlying C implementation? GCC / glibc, perhaps? This is essential information. – John Bollinger Jan 25 '21 at 17:52
  • I inserted the code as text :/ But won't do it again, next time insert the code yourself please ! – TheEagle Jan 25 '21 at 17:56
  • 4
    Why do you want to use `strcpy_s()`? this function is part of an extension to the C Standard (Annex K) quite specific to Microsoft platforms. Other platforms might not implement it and it should be noted that Microsoft's implementation is inconsistent with the C Standard' Annex K they contributed to. It is probably a good idea to avoid it altogether. – chqrlie Jan 25 '21 at 18:01
  • 1
    Consider just using `strcpy()` instead of `strcpy_s()`. The so-called "security enhanced" functions are an optional feature of standard C, and not widely implemented. The main implementation of note is Microsoft's, and that does not fully conform to the language standard. Moreover, the supposed extra security is mostly illusory. The main security benefit is *behavioral*: by insisting that the `_s` versions of standard functions be used, one forces developers to pay the attention to buffer-size and related issues that they ought to pay anyway. – John Bollinger Jan 25 '21 at 18:05
  • Likely a dupe of https://stackoverflow.com/questions/40045973/strcpy-s-not-working-with-gcc – John Bollinger Jan 25 '21 at 18:08
  • @JohnBollinger The example copies 11 characters from a 14 character string, `strcpy()` will overrun in this case. `strncpy()` perhaps? – Clifford Jan 26 '21 at 14:39
  • I had overlooked that, @Clifford, and it's an interesting point because the example *does not* copy 11 characters. It copies nothing because it has a constraint violation. This exhibits my point: the programmer is still obligated to ensure that the destination space is large enough to accommodate the copy. If they express the size correctly to `strcpy_s()` and the source is too large then the program fails in a predictable manner -- which is the benefit, to the extent there is one. If they express the destination size incorrectly then the benefit of using `strcpy_s` is unclear. – John Bollinger Jan 26 '21 at 15:43
  • `strncpy()` is not a good alternative here because it will not provide a string terminator if the source string is at least is long as the specified destination size. If it is acceptable to generate a truncated copy, however, then `strncat()` can do that, ensuring termination. – John Bollinger Jan 26 '21 at 15:56
  • @JohnBollinger I covered that point in my answer. `strncat()` as a strcpy requires that the first element is initialised nul - that is little different that my requirement that the end be initialised to nul - except perhaps the beginning is always in the same place, so easier to get right perhaps. Best solution perhaps is to write your own intrinsically safe wrappers with the semantics and behaviour you want. – Clifford Jan 26 '21 at 16:56

1 Answers1

0

strcpy_s() may not be declared without __STDC_WANT_LIB_EXT1__:

#define __STDC_WANT_LIB_EXT1__
#include <string.h>

If the implementation does not define __STDC_LIB_EXT1__ then the extension is not available in your library.

Since you are not checking the errno_t return value from strcpy_s, you would do better perhaps to use the more broadly supported strncpy().

The advantages of strcpy_s() (or even strncpy_s()) are that they tell you when the have failed, and on success guarantee the destination is NUL terminated. But since you are not checking for error, there is little advantage. That can be resolved by explicitly ensuring that s[11] is NUL by for example:

Zero initialisation:

char s[12] = {0} ;

or assignment:

s[sizeof(s) - 1] = '\0' ;
#include <string.h>
#include <stdio.h>

int main(void) 
{
    static int foo = 0;
    char s[12] = {0} ;
    char *t = "01234567890123"
    printf("foo %p\n s %p\n", &foo, s);

    strncpy(s, t, sizeof(s) - 1) ) ;

    return 0 ;
}

Note that in this case strncpy() will copy 11 characters to s, and will not write a NUL terminator. In this case I have zero initialised the entire array, but in cases where destination is not known to be zero initialised or the length variable then a safer idiom is to add the terminator :

strncpy(s, t, len ) ;
s[len] = '\0' ;

Or specifically in this example:

strncpy(s, t, sizeof(s) - 1) ) ;
s[sizeof(s) - 1)] = '\0' ;
Clifford
  • 88,407
  • 13
  • 85
  • 165
  • 1
    reminder that [`strncpy` is actually considered dangerous](https://stackoverflow.com/a/25746647), the more intuitive `strlcpy` is prefered if available – Mgetz Jan 25 '21 at 18:41
  • @Mgetz Good to know. I have added stuff since that mitigate some of the `strncpy()` issues. I suspect `strlcpy()` is less widely supported and on some platforms you end up with the same problem as `strrcpy_s`. I code for embedded systems and somtimes Windows, and seldom for Linux. – Clifford Jan 25 '21 at 18:45