将c11标准与clang一起使用以使用strcpy_s [英] using c11 standard with clang for use of strcpy_s

查看:329
本文介绍了将c11标准与clang一起使用以使用strcpy_s的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行OS X Sierra,并尝试编译使用 strcpy_s 的ac程序,但是我安装的clang编译器正在使用c99标准,但是我已阅读的内容 strcpy_s需要c11。

I'm running OS X Sierra and trying to compile a c program that uses strcpy_s, but my installed clang compiler is using the c99 standard, but from what I've read strcpy_s requires c11.

这是我要编译的代码

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

int main(void)
{
    char source[] = "Test string";
    char destination[50];
    if(strcpy_s(destination, sizeof(destination), source))
        printf("string copied - %s",destination);

    return 0;
}

这是我用来编译的命令

$ clang copytest.c -o copytest
copytest.c:11:5: warning: implicit declaration of function 'strcpy_s' is invalid in C99 [-Wimplicit-function-declaration]
        if(strcpy_s(copied_string, sizeof(copied_string), source))
           ^
1 warning generated.
Undefined symbols for architecture x86_64:
  "_strcpy_s", referenced from:
      _main in copytest-e1e05a.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I已经尝试使用标准标志进行编译...

I've tried compiling with the standard flag...

clang -std = c11 copytest.c -o copytest

,但是我得到了完全相同的在c99中无效的警告。我也尝试使用gcc进行编译,但仍然收到相同的c99警告。

but I get the same exact "invalid in c99" warning. I've also tried compiling with gcc instead, and I still get the same c99 warning.

我尝试通过自制程序进行升级,显示以下内容

I tried upgrading via homebrew which shows the following


警告:gcc 9.2 .0已经安装并且是最新的

Warning: gcc 9.2.0 is already installed and up-to-date

我的Clang版本是9.0.0

I have clang version 9.0.0

$ clang -v
Apple LLVM version 9.0.0 (clang-900.0.39.2)

我的xcode版本是Xcode 9.2,从我读过的所有内容中都应该带有c11支持。

My xcode version is Xcode 9.2, which from everything I've read should come with c11 support.

我在编译时做错了什么,我的代码本身是错误的吗? 是唯一的我在这里找到类似的问题,但甚至没有答案。谢谢

Am I doing something wrong with the compiling, is my code itself incorrect? This is the only similar question I found on here, but it didn't even have an answer. Thanks

推荐答案

_s 函数是可选 2011 C标准的组件(附件K ),据我所知,它们从未实现为任何C库的集成部分。可移植代码不能依赖于它们的可用性。 (用于Windows的Microsoft C编译器使用名称相同但语义不同(有时甚至是不同的参数列表)实现了一组重叠的函数,并且至少有一个附加实施确实存在。请参阅此旧答案以及更长的问答时间

The _s functions are an optional component of the 2011 C standard (Annex K), and, to the best of my knowledge, they have never been implemented as an integrated part of any C library. Portable code cannot rely on their availability. (Microsoft's C compilers for Windows implement an overlapping set of functions with the same names but different semantics (and sometimes even a different argument list), and at least one bolt-on implementation does exist. See this old answer, and the much longer question and answer it links to, for more detail.)

此外, _s 函数不能解决他们打算解决的问题(不安全的字符串处理);有必要针对每一个 strcpy 的使用,对实际思想进行适当的修正,而不是全局地搜索和替换 strcpy strcpy_s 等,如附件K的作者所希望的那样。如果您对适当的解决方案进行了适当的思考,则不需要 _s 中的任何函数来实现它。例如,这是示例程序的固定版本:

Also, the _s functions do not solve the problem that they were intended to solve (unsafe string handling); it is necessary to put actual thought into a proper fix for each use of strcpy, instead of globally search-and-replacing strcpy with strcpy_s, etc., as was the hope of the authors of Annex K. If you do put appropriate amounts of thought into a proper fix, you won't need any of the _s functions to implement it. For instance, here's a fixed version of your example program:

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

int main(void)
{
    char source[] = "Test string";
    char destination[50];

    size_t srclen = strlen(source);
    if (srclen + 1 > sizeof destination) {
        fprintf(stderr, "string too long to copy - %zu bytes, need %zu\n",
                sizeof destination, srclen + 1);
        return 1;
    } else {
        memcpy(destination, source, srclen + 1);
        printf("string copied - %s\n", destination);
        return 0;
    }
}

这是一个更好的版本:

#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    if (argc != 2) {
        fprintf(stderr, "usage: ./test 'message of arbitrary length'\n");
        return 1;
    }
    char *destination = strdup(argv[1]);
    if (!destination) {
        perror("strdup");
        return 1;
    }
    printf("string copied - '%s'\n", destination);
    free(destination);
    return 0;
}

因此:切勿使用任何 _s 函数。如果您需要编写一个在Windows上编译且没有警告的程序,请将 #define _CRT_SECURE_NO_WARNINGS 1 放在每个文件的顶部,以使MSVC停止提供错误建议。

Therefore: Never use any of the _s functions. If you need to write a program that compiles on Windows with no warnings, put #define _CRT_SECURE_NO_WARNINGS 1 at the top of each file to make MSVC stop giving you bad advice.

这篇关于将c11标准与clang一起使用以使用strcpy_s的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆